1 /*************************************************************/
2 /* NET_SEND.CXX by Oliver Delise */
4 /* e-mail: delise@mail.isis.de */
5 /* www: http://www.isis.de/members/odelise/progs/flightgear */
8 /* The author of this program offers no waranty at all */
9 /* about the correct execution of this software material. */
10 /* Furthermore, the author can NOT be held responsible for */
11 /* any physical or moral damage caused by the use of this */
14 /* This is an interactive standalone Tool to communicate */
15 /* with any FlightGear-Deamon. */
16 /* This is Open Source Software with many parts */
17 /* shamelessly stolen from others... */
19 /* -> This program will use a TCP port listening on a */
20 /* remote or local host inside the range you give to it. */
21 /* I offer no warranty over the accuracy though :) */
22 /* There are 3 verbose modes: No info, service info, and */
23 /* full info. No info is good of you only want the list */
24 /* of the ports, no more info. The best mode is Full */
25 /* info, as you get error information,etc. The main */
26 /* output is STDOUT, and ALL the errors go to STDERR. */
28 /* History: v0.1pre-alpha: May 25 1999 -> First release */
29 /* v0.1-alpha Nov 11 1999 */
30 /* v0.1-beta Jan 16 2000 -> libc5, glibc2.0 */
31 /* glibc-2.1 issues fixed */
32 /*************************************************************/
38 /* I prefer NHV's decl. */
39 #include <simgear/constants.h>
41 #include <Cockpit/hud.hxx>
43 #include <Main/globals.hxx>
44 #include <Main/viewmgr.hxx>
49 #include <arpa/inet.h>
52 struct sockaddr_in address;
53 struct sockaddr_in my_address;
56 //#if defined( __CYGWIN__ )
58 //const char *const *sys_errlist = _sys_errlist;
61 //extern const char *const sys_errlist[];
64 //#if defined( __CYGWIN__ )
70 //extern const char *const sys_errlist[];
72 /* -dlw- I fixed a few of the cases, but please make non externally used */
73 /* symbols static to avoid possible linker conflicts */
74 int current_port = 10000;
75 u_short base_port = 10000;
76 u_short end_port = 10010;
78 static int verbose = 0;
79 static struct hostent *host_info, *f_host_info;
80 static struct servent *service_info;
81 static struct utsname myname;
85 int fgd_len_msg = 1, fgd_reply_len, fgd_status, fgd_ele_len, fgd_curpos, fgd_cnt, fgd_ppl,
86 fgd_ppl_old, fgd_loss, net_r;
88 char *fgd_job, *fgd_callsign, *fgd_name, *fgd_ip, *fgd_mcp_ip;
89 char *buffp, *src_host, *fgd_host, *fgfs_host, *fgfs_pilot, *fgd_txt;
91 extern sgMat4 sgFGD_VIEW;
92 extern ssgRoot *fgd_scene;
93 extern char *FGFS_host, *net_callsign;
97 const int listTrue = 0;
98 const int listFalse= -1;
101 /* unsigned */ char ipadr[16], callsign[16];
102 /* unsigned */ char lon[8], lat[8], alt[8], roll[8], pitch[8], yaw[8];
103 float lonf, latf, altf, speedf, rollf, pitchf, yawf;
105 ssgSelector *fgd_sel;
106 ssgTransform *fgd_pos;
107 struct list_ele *next, *prev;
110 struct list_ele *head, *tail, *act, *test, *incoming, *boss, *other; /* fgd_msg; */
112 /*...Create head and tail of list */
113 void list_init( void) {
115 incoming = (struct list_ele*) malloc(sizeof(struct list_ele));
116 boss = (struct list_ele*) malloc(sizeof(struct list_ele));
117 other = (struct list_ele*) malloc(sizeof(struct list_ele));
118 head = (struct list_ele*) malloc(sizeof(struct list_ele));
119 tail = (struct list_ele*) malloc(sizeof(struct list_ele));
120 if (head == NULL || tail == NULL) { printf("Out of memory\n"); exit(1); }
122 tail->ipadr[0] = 255;
124 head->prev = tail->prev = head;
125 head->next = tail->next = tail;
126 act = head; /* put listpointer to beginning of list */
129 void list_output( void) {
132 void list_search( char name[16]) {
134 if (strcmp(name, head->next->ipadr) <= 0) act = head;
135 else if (strcmp(name, tail->prev->ipadr) > 0) act = tail->prev;
137 int vergleich = strcmp(name, act->ipadr);
139 while (strcmp(name, act->next->ipadr) > 0) {
142 else if (vergleich < 0)
143 while (strcmp(name, act->ipadr) < 0) {
147 while (strcmp(name, act->ipadr) == 0) {
153 void list_insert( char newip[16]) {
154 struct list_ele *new_ele;
156 new_ele = (struct list_ele*) malloc(sizeof(struct list_ele));
157 if (new_ele == NULL) { printf("Out of memory\n"); exit(1); }
158 strcpy(new_ele->ipadr, newip);
159 /* setting default */
160 strcpy(new_ele->callsign, "not assigned");
161 /* generating ssg stuff */
162 new_ele->fgd_sel = new ssgSelector;
163 new_ele->fgd_pos = new ssgTransform;
165 ssgEntity *fgd_obj = ssgLoadAC( "tuxcopter.ac" );
166 fgd_obj->clrTraversalMaskBits( SSGTRAV_HOT );
167 new_ele->fgd_pos->addKid( fgd_obj );
168 new_ele->fgd_sel->addKid( new_ele->fgd_pos );
169 ssgFlatten( fgd_obj );
170 ssgStripify( new_ele->fgd_sel );
172 fgd_scene->addKid( new_ele->fgd_sel );
173 fgd_scene->addKid( fgd_obj );
174 /* ssgKid "born" and inserted into scene */
177 new_ele->next = act->next;
178 act->next->prev = act->next = new_ele;
181 void list_setval( char newip[16]) {
184 strcpy( act->next->callsign, incoming->callsign);
185 printf("Callsign %s\n", act->next->callsign);
189 void list_clear( char clrip[16]) {
190 struct list_ele *clr_ele;
193 if ( strcmp( clrip, act->next->ipadr))
194 printf("....Name %s nicht vorhanden", clrip);
197 act->next = act->next->next;
198 act->next->prev = act;
203 int list_not_in( char name[16]) {
207 while ((test != tail) && (i==listTrue)) {
208 i = (strcmp(test->ipadr, name) ? listTrue : listFalse);
210 if (verbose != 0) printf("list_not_in : %d\n",i);
215 void fgd_print_Mat4( const sgMat4 m ) {
216 printf("0.0 %f 0.1 %f 0.2 %f 0.3 %f\n",
217 m[0][0], m[0][1], m[0][2], m[0][3] );
218 printf("1.0 %f 1.1 %f 1.2 %f 1.3 %f\n",
219 m[1][0], m[1][1], m[1][2], m[1][3] );
220 printf("2.0 %f 2.1 %f 2.2 %f 2.3 %f\n",
221 m[2][0], m[2][1], m[2][2], m[2][3] );
222 printf("3.0 %f 3.1 %f 3.2 %f 3.3 %f\n",
223 m[3][0], m[3][1], m[3][2], m[3][3] );
228 /* Let's init a few things */
229 printf("MCP: Allocating memory...");
230 buffp = (char *) malloc(1024); /* No I don't check if there are another KB */
231 fgd_job = (char *) malloc(8);
232 fgd_host = (char *) malloc(64);
233 fgd_callsign = (char *) malloc(64);
234 fgd_name = (char*) malloc(64);
235 fgd_ip = (char *) malloc(16);
236 fgd_mcp_ip = (char *) malloc(16);
237 fgfs_host = (char *) malloc(64);
238 fgfs_pilot = (char *) malloc(64);
239 src_host = (char *) malloc(64);
240 fgd_txt = (char *) malloc(1024);
241 printf("ok\nMCP: Initializing values...");
242 strcpy( fgd_job, "xxx");
243 strcpy( fgd_host, "Olk");
244 strcpy( fgd_callsign, "Unknown");
245 strcpy( fgd_name, "Unknown");
246 strcpy( fgd_ip, (char *) inet_ntoa(address.sin_addr));
247 strcpy( fgd_txt, "");
252 boss->speedf = 100.95;
255 boss->yawf = 456.789;
257 bzero((char *)&address, sizeof(address));
258 address.sin_family = AF_INET;
259 /* determinating the source/sending host */
260 if (uname(&myname) == 0) strcpy(src_host , myname.nodename);
261 printf("MCP: I'm running on HOST : %s ", src_host);
262 if (host_info = gethostbyname( src_host)) {
263 bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
264 strcpy((char *) fgd_mcp_ip, (char *) inet_ntoa(address.sin_addr));
266 printf("IP : %s\n", fgd_mcp_ip);
267 FGFS_host = src_host;
268 /* resolving the destination host, here fgd's host */
269 if (verbose == 2) printf(" Resolving default DEAMON: %s ->", fgd_host);
270 if (host_info = gethostbyname( fgd_host)) {
271 bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
272 strcpy((char *) fgd_ip, (char *) inet_ntoa(address.sin_addr));
274 printf(" resolved\n FGD running on HOST : %s", fgd_host);
275 printf(" IP : %s\n", fgd_ip);
277 } else if ((address.sin_addr.s_addr = inet_addr( fgd_host)) == INADDR_NONE) {
278 fprintf(stderr," Could not get %s host entry !\n", fgd_host);
279 printf(" NOT resolved !!!\n");
281 } else if (verbose == 2) printf(" address valid\n");
283 if ((base_port > end_port) || ((short)base_port < 0)) {
284 fprintf(stderr,"Bad port range : start=%d end=%d !\n",base_port,end_port);
286 } else if (verbose == 2) {
287 printf(" Port range: %d to %d\n",base_port,end_port);
291 int net_resolv_fgd( char *fgd_host_check ) {
293 char *fgd_ip_check = "";
295 /* resolving the destination host, here fgd's host */
297 if (verbose == 2) printf(" Resolving default DEAMON: %s ->", fgd_host_check);
298 if (host_info = gethostbyname( fgd_host_check)) {
299 bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
300 strcpy((char *) fgd_ip_check, (char *) inet_ntoa(address.sin_addr));
301 fgd_ip = fgd_ip_check;
303 printf(" FGD: resolved\nFGD: running on HOST : %s", fgd_host_check);
304 printf(" IP : %s\n", fgd_ip_check);
305 strcpy( fgd_host, fgd_host_check);
308 } else if ((address.sin_addr.s_addr = inet_addr( fgd_host)) == INADDR_NONE) {
309 fprintf(stderr,"FGD: Could not get %s host entry !\n", fgd_host_check);
310 printf(" FGD: NOT resolved !!!\n");
314 } else if (verbose == 2) printf(" address valid\n");
316 if ((base_port > end_port) || ((short)base_port < 0)) {
317 fprintf(stderr,"Bad port range : start=%d end=%d !\n",base_port,end_port);
321 } else if (verbose == 2) {
322 printf(" Port range: %d to %d\n",base_port,end_port);
328 void fgd_send_com( char *FGD_com, char *FGFS_host) {
331 // current_port = base_port;
332 if (verbose == 2) printf(" Sending : %s\n", FGD_com);
333 // while (current_port <= end_port) {
334 /* fprintf(stderr,"Trying port: %d\n",current_port); */
335 sock = socket(PF_INET, SOCK_STREAM, 0);
338 // fprintf(stderr, "Error assigning master socket: %s\n",sys_errlist[errno]);
339 fprintf(stderr, "Error assigning master socket: %s\n",
341 /* must check how severe this really is */
345 address.sin_port = htons(current_port);
346 if (verbose == 2) printf(" address.sin_port : %d\n",htons(address.sin_port));
348 f_host_info = gethostbyname(src_host);
350 //printf ("src_host : %s", ntohs(f_host_info->h_addr));
352 if (connect(sock, (struct sockaddr *)&address, sizeof(address)) == 0) {
353 /* FIXME: make a single string instead of sending elements */
355 fgd_len_msg = (int) sizeof(f_host_info->h_addr);
356 /* send length of sender-ip */
357 write( sock, &fgd_len_msg,1);
359 write( sock, f_host_info->h_addr, fgd_len_msg);
361 write( sock, FGD_com, 1);
362 /* send length of dummy-string, for the moment with _WHO_ to execute commando
363 here: his length of ip */
364 f_host_info = gethostbyname(FGFS_host);
365 fgd_len_msg = (int) sizeof(f_host_info->h_addr);
366 write( sock, &fgd_len_msg,1);
367 /* send dummy-string, for the moment with _WHO_ to execute commando
369 write( sock, f_host_info->h_addr, fgd_len_msg);
372 /* Here we send subsequent data... */
373 switch ( (char) FGD_com[0] - 0x30) {
374 case 5: fgd_len_msg = strlen( net_callsign);
375 write( sock, &fgd_len_msg,1);
376 /* send string, for the moment, here: callsign */
377 write( sock, net_callsign, fgd_len_msg);
378 /* Lon, Lat, Alt, Speed, Roll, Pitch, Yaw
379 hope this sprintf call is not too expensive */
380 sprintf( fgd_txt, " %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f",
381 // boss->latf, boss->lonf, boss->altf, boss->speedf,
382 // boss->rollf, boss->pitchf, boss->yawf);
384 Must decide if it's better to send values "as are" or convert them for
385 deamon, better is to let deamon make the job. Anyway this will depend on
386 speed loss/gain in network-area...
388 get_latitude(), get_longitude(), get_altitude(),
389 get_speed(), get_roll()*SGD_RADIANS_TO_DEGREES,
390 get_pitch()*SGD_RADIANS_TO_DEGREES, get_heading());
391 write( sock, fgd_txt, 56);
394 /* Here sending the previously calculated view.Mat4 by FGFS */
395 case 17: if (verbose == 2) printf("Checkpoint\n");
396 sgCopyMat4(sgFGD_COORD, globals->get_current_view()->get_VIEW());
399 printf("current_view\n");
400 fgd_print_Mat4( globals->get_current_view()->get_VIEW());
401 printf("FGD_COORD\n");
402 fgd_print_Mat4( sgFGD_COORD);
404 fgd_len_msg = strlen( net_callsign);
405 write( sock, &fgd_len_msg,1);
406 /* send string, for the moment, here: callsign */
407 write( sock, net_callsign, fgd_len_msg);
408 /* MATRIX-variant of Lon, Lat etc...
409 hope this sprintf call is not too expensive */
410 fgd_len_msg = sprintf( fgd_txt, " %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
411 sgFGD_COORD[0][0], sgFGD_COORD[0][1], sgFGD_COORD[0][2], sgFGD_COORD[0][3],
412 sgFGD_COORD[1][0], sgFGD_COORD[1][1], sgFGD_COORD[1][2], sgFGD_COORD[1][3],
413 sgFGD_COORD[2][0], sgFGD_COORD[2][1], sgFGD_COORD[2][2], sgFGD_COORD[2][3],
414 sgFGD_COORD[3][0], sgFGD_COORD[3][1], sgFGD_COORD[3][2], sgFGD_COORD[3][3]);
415 fgd_txt[fgd_len_msg] = 0;
416 write( sock, fgd_txt, fgd_len_msg+1);
422 /* be verbose, this goes later into own (*void) */
423 if (verbose == 2) printf(" Message : %s\n", FGD_com);
425 case 0: // printf("%d\n",current_port);
427 case 1: service_info = getservbyport(htons(current_port),"tcp");
429 printf("%d -> service name unknown\n",current_port);
431 printf("%d -> %s\n",current_port,service_info->s_name);
434 case 2: service_info = getservbyport(htons(current_port),"tcp");
436 printf(" Port %d found. Service name unknown\n",current_port);
438 printf(" Port %d found. Service name: %s\n",current_port,service_info->s_name);
442 } else if (errno == 113) {
443 fprintf(stderr,"No route to host !\n");
444 /* must check this */
447 /* fprintf(stderr,"Error %d connecting socket %d to port %d: %s\n",
448 errno,sock,current_port,sys_errlist[errno]); */
450 // service_info = getservbyport(htons(current_port),"tcp");
451 // if (!service_info) {
455 /* The Receiving Part, fgd returns errormessages, succes, etc... */
457 fgd_status = recv( sock, (char *) buffp, 5, MSG_WAITALL);
458 if (verbose == 2) printf(" status %d\n", fgd_status);
460 // while ( (fgd_status != 5) && (fgd_status != 0) );
461 while ( (fgd_status == -1) || (fgd_status == -1) );
462 fgd_reply_len = (unsigned char) buffp[3] + (unsigned char) buffp[4] * 256;
464 printf(" Got reply : %x %x %x MSG length %d Bytes\n",
465 buffp[0], buffp[1], buffp[2], fgd_reply_len);
467 if (strncmp( buffp, "FGD", 3) == 0) {
468 switch ( (char) FGD_com[0] - 0x30) {
470 abc = read( sock, fgd_name, fgd_reply_len);
471 if (verbose == 2) printf("readwert: %d", abc);
472 // fgd_name[buffp[3]] = 0;
473 printf("FGD: FlightGear-Deamon %s detected\n", fgd_name);
475 case 1: read( sock, fgd_txt, fgd_reply_len);
476 printf("FGD: Registering Host %s\n", fgd_txt);
478 case 2: printf("FGD: Showing registered Hosts at %s\n", fgd_host);
479 if ( fgd_reply_len != 5) {
480 /* FIXME: replace with SELECT to avoid broken pipes, known bug (-; */
482 fgd_status = recv( sock, fgd_txt, fgd_reply_len - 5,
484 // printf(" status %d\n", fgd_status);
486 // while ( (fgd_status != 5) && (fgd_status != 0) );
487 while ( (fgd_status == -1) || (fgd_status == -1) );
488 // read( sock, fgd_txt, fgd_reply_len - 5);
490 for (fgd_cnt = 1; fgd_cnt < (fgd_txt[0]+1); fgd_cnt++) {
491 fgd_ele_len = fgd_txt[fgd_curpos];
492 bcopy( &fgd_txt[fgd_curpos], fgfs_host, fgd_ele_len);
493 // fgfs_host[fgd_ele_len] = 0;
494 fgd_curpos += fgd_ele_len + 1;
495 if (verbose == 2) printf(" #%d %s\n", fgd_cnt, fgfs_host);
499 case 5: printf("FGD: Receiving data from Host %s\n", FGFS_host);
500 read( sock, fgd_txt, buffp[3]);
501 fgd_txt[buffp[3]] = 0;
503 if (strcmp(fgd_txt, "UNKNOWN") == 0) {
504 printf("FGD: Host not in list, sorry...\n");
506 else printf("FGD: Data from Host %s received\n", fgd_txt);
508 /* This has problem with glibc-2.1
509 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
510 if (verbose == 2) printf("FGD: Data from Host %s received\n", fgd_txt);
512 else if (verbose == 2) printf("FGD: Host not in list, sorry...\n");
515 case 17: if (verbose == 2) printf("FGD: Receiving Mat4 data from Host %s\n", FGFS_host);
516 read( sock, fgd_txt, fgd_reply_len);
517 // fgd_txt[buffp[3]] = 0;
518 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
519 if (verbose == 2) printf("FGD: Mat4 Data from Host %s received\n", fgd_txt);
521 else printf("FGD: Host not in list, sorry...\n");
523 case 6: printf("FGD: Sending data to Host %s\n", FGFS_host);
525 /* FIXME: replace with SELECT */
526 if (verbose == 2) printf("Noch %d bytes\n", (unsigned char) buffp[3]);
528 fgd_status = recv( sock, fgd_txt, (unsigned char) buffp[3]-4, MSG_PEEK);
529 if (verbose == 2) printf("Status %d\n", fgd_status);
531 while ( (fgd_status == 4) || (fgd_status == -1) );
532 // while ( (fgd_status == -1) || (fgd_status == -1) );
533 read( sock, fgd_txt, buffp[3]-4);
535 fgd_ppl_old = fgd_ppl;
536 fgd_ppl = fgd_txt[0];
537 /* Check if list has changed (pilot joined/left) */
538 if (fgd_ppl != fgd_ppl_old) {
539 printf(" List changed!!!\n");
540 for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
541 if (verbose == 2) printf(" Checkpoint\n");
542 incoming = head->next;
543 if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
545 printf(" Clearing entry.\n");
546 list_clear(incoming->ipadr);
551 incoming = head->next;
552 for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
554 fgd_ele_len = fgd_txt[fgd_curpos-1];
555 bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
556 incoming->ipadr[fgd_ele_len] = 0;
557 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
559 fgd_ele_len = fgd_txt[fgd_curpos-1];
560 bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
561 incoming->callsign[fgd_ele_len] = 0;
562 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
565 printf(" #%d %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
566 printf(" curpos:%d\n", fgd_curpos);
567 sscanf( &fgd_txt[fgd_curpos]," %7f %7f %7f %7f %7f %7f %7f",
568 &incoming->latf, &incoming->lonf,
569 &incoming->altf, &incoming->speedf, &incoming->rollf,
570 &incoming->pitchf, &incoming->yawf);
571 printf(" lat :%7.3f\n lon :%7.3f\n alt :%7.3f\n speed :%7.3f\n roll :%7.3f\n pitch :%7.3f\n yaw :%7.3f\n",
572 incoming->latf, incoming->lonf, incoming->altf, incoming->speedf,
573 incoming->rollf, incoming->pitchf, incoming->yawf);
576 incoming = incoming->next;
579 } /* end if "data available" */
580 /* Here reading the answer of completed command by fgd */
581 /* read( sock, fgd_txt, buffp[3]);
582 fgd_txt[buffp[3]] = 0;
583 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
584 if (verbose == 2) printf("FGD: Data to Host sent\n");
586 else printf("FGD: Host not in list, sorry...\n");
589 case 18: if (verbose == 2) printf("FGD: Sending Mat4 data to Host %s\n", FGFS_host);
590 if (fgd_reply_len != 5) {
591 /* FIXME: replace with SELECT */
592 if (verbose == 2) printf("Noch %d bytes\n", fgd_reply_len);
594 fgd_status = recv( sock, fgd_txt, fgd_reply_len - 5, MSG_WAITALL);
595 if (verbose == 2) printf("Status %d\n", fgd_status);
597 // while ( (fgd_status == 4) || (fgd_status == -1) );
598 while ( (fgd_status == -1) || (fgd_status == -1) );
599 // read( sock, fgd_txt, fgd_reply_len - 5);
601 fgd_ppl_old = fgd_ppl;
602 fgd_ppl = fgd_txt[0];
603 /* Check if list has changed (pilot joined/left) */
604 if (fgd_ppl != fgd_ppl_old) {
605 printf(" List changed!!!\n");
606 for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
607 if (verbose == 2) printf(" Checkpoint\n");
608 incoming = head->next;
609 if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
611 printf(" Clearing entry.\n");
612 list_clear(incoming->ipadr);
617 incoming = head->next;
618 for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
620 fgd_ele_len = fgd_txt[fgd_curpos-1];
621 bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
622 incoming->ipadr[fgd_ele_len] = 0;
623 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
625 fgd_ele_len = fgd_txt[fgd_curpos-1];
626 bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
627 incoming->callsign[fgd_ele_len] = 0;
628 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
631 printf(" #%d %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
632 printf(" curpos:%d\n", fgd_curpos);
634 fgd_len_msg = strlen ( &fgd_txt[fgd_curpos]);
635 sscanf( &fgd_txt[fgd_curpos]," %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
636 &incoming->sgFGD_COORD[0][0], &incoming->sgFGD_COORD[0][1], &incoming->sgFGD_COORD[0][2], &incoming->sgFGD_COORD[0][3],
637 &incoming->sgFGD_COORD[1][0], &incoming->sgFGD_COORD[1][1], &incoming->sgFGD_COORD[1][2], &incoming->sgFGD_COORD[1][3],
638 &incoming->sgFGD_COORD[2][0], &incoming->sgFGD_COORD[2][1], &incoming->sgFGD_COORD[2][2], &incoming->sgFGD_COORD[2][3],
639 &incoming->sgFGD_COORD[3][0], &incoming->sgFGD_COORD[3][1], &incoming->sgFGD_COORD[3][2], &incoming->sgFGD_COORD[3][3]);
642 printf("Incoming Mat4\n");
643 fgd_print_Mat4( incoming->sgFGD_COORD );
645 fgd_curpos += fgd_len_msg + 2;
646 incoming = incoming->next;
649 } /* end if "data available" */
650 /* The first view-Mat4 is somebody else */
651 sgCopyMat4(sgFGD_VIEW, head->next->sgFGD_COORD);
653 /* Here reading the answer of completed command by fgd */
654 /* read( sock, fgd_txt, buffp[3]);
655 // fgd_txt[buffp[3]] = 0;
656 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
657 if (verbose == 2) printf("FGD: Mat4 Data to Host sent\n");
659 else printf("FGD: Host not in list, sorry...\n");
662 case 8: printf("FGD: Unregistering Host %s\n", FGFS_host);
663 read( sock, fgd_txt, buffp[3]);
664 fgd_txt[buffp[3]] = 0;
666 while (test != tail) {
667 list_clear( test->ipadr );
672 if (strcmp(fgd_txt, "UNKNOWN") == 0) {
673 printf("FGD: Host not in list, sorry...\n");
675 else printf("FGD: Host %s unregistered\n", fgd_txt);
677 /* This does not work on glibc-2.1
678 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
679 printf("FGD: Host %s unregistered\n", fgd_txt);
681 else printf("FGD: Host not in list, sorry...\n");
684 case 9: printf(" Shutdown FlightGear-Deamon %s .\n", fgd_name);
688 } else printf(" Huh?: no deamon present, yuk!!!\n");
694 if (verbose == 2) printf("fgd_com completed.\n");