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>
45 #include <Model/loader.hxx>
50 #include <arpa/inet.h>
53 struct sockaddr_in address;
54 struct sockaddr_in my_address;
57 //#if defined( __CYGWIN__ )
59 //const char *const *sys_errlist = _sys_errlist;
62 //extern const char *const sys_errlist[];
65 //#if defined( __CYGWIN__ )
71 //extern const char *const sys_errlist[];
73 /* -dlw- I fixed a few of the cases, but please make non externally used */
74 /* symbols static to avoid possible linker conflicts */
75 int current_port = 10000;
76 u_short base_port = 10000;
77 u_short end_port = 10010;
79 static int verbose = 0;
80 static struct hostent *host_info, *f_host_info;
81 static struct servent *service_info;
82 static struct utsname myname;
86 int fgd_len_msg = 1, fgd_reply_len, fgd_status, fgd_ele_len, fgd_curpos, fgd_cnt, fgd_ppl,
87 fgd_ppl_old, fgd_loss, net_r;
89 char *fgd_job, *fgd_callsign, *fgd_name, *fgd_ip, *fgd_mcp_ip;
90 char *buffp, *src_host, *fgd_host, *fgfs_host, *fgfs_pilot, *fgd_txt;
92 extern sgMat4 sgFGD_VIEW;
93 extern ssgRoot *fgd_scene;
94 extern char *FGFS_host, *net_callsign;
98 const int listTrue = 0;
99 const int listFalse= -1;
102 /* unsigned */ char ipadr[16], callsign[16];
103 /* unsigned */ char lon[8], lat[8], alt[8], roll[8], pitch[8], yaw[8];
104 float lonf, latf, altf, speedf, rollf, pitchf, yawf;
106 ssgSelector *fgd_sel;
107 ssgTransform *fgd_pos;
108 struct list_ele *next, *prev;
111 struct list_ele *head, *tail, *act, *test, *incoming, *boss, *other; /* fgd_msg; */
113 /*...Create head and tail of list */
114 void list_init( void) {
116 incoming = (struct list_ele*) malloc(sizeof(struct list_ele));
117 boss = (struct list_ele*) malloc(sizeof(struct list_ele));
118 other = (struct list_ele*) malloc(sizeof(struct list_ele));
119 head = (struct list_ele*) malloc(sizeof(struct list_ele));
120 tail = (struct list_ele*) malloc(sizeof(struct list_ele));
121 if (head == NULL || tail == NULL) { printf("Out of memory\n"); exit(1); }
123 tail->ipadr[0] = 255;
125 head->prev = tail->prev = head;
126 head->next = tail->next = tail;
127 act = head; /* put listpointer to beginning of list */
130 void list_output( void) {
133 void list_search( char name[16]) {
135 if (strcmp(name, head->next->ipadr) <= 0) act = head;
136 else if (strcmp(name, tail->prev->ipadr) > 0) act = tail->prev;
138 int vergleich = strcmp(name, act->ipadr);
140 while (strcmp(name, act->next->ipadr) > 0) {
143 else if (vergleich < 0)
144 while (strcmp(name, act->ipadr) < 0) {
148 while (strcmp(name, act->ipadr) == 0) {
154 void list_insert( char newip[16]) {
155 struct list_ele *new_ele;
157 new_ele = (struct list_ele*) malloc(sizeof(struct list_ele));
158 if (new_ele == NULL) { printf("Out of memory\n"); exit(1); }
159 strcpy(new_ele->ipadr, newip);
160 /* setting default */
161 strcpy(new_ele->callsign, "not assigned");
162 /* generating ssg stuff */
163 new_ele->fgd_sel = new ssgSelector;
164 new_ele->fgd_pos = new ssgTransform;
166 ssgEntity *fgd_obj = globals->get_model_loader()->load_model( "tuxcopter.ac" );
167 fgd_obj->clrTraversalMaskBits( SSGTRAV_HOT );
168 new_ele->fgd_pos->addKid( fgd_obj );
169 new_ele->fgd_sel->addKid( new_ele->fgd_pos );
170 ssgFlatten( fgd_obj );
171 ssgStripify( new_ele->fgd_sel );
173 fgd_scene->addKid( new_ele->fgd_sel );
174 fgd_scene->addKid( fgd_obj );
175 /* ssgKid "born" and inserted into scene */
178 new_ele->next = act->next;
179 act->next->prev = act->next = new_ele;
182 void list_setval( char newip[16]) {
185 strcpy( act->next->callsign, incoming->callsign);
186 printf("Callsign %s\n", act->next->callsign);
190 void list_clear( char clrip[16]) {
191 struct list_ele *clr_ele;
194 if ( strcmp( clrip, act->next->ipadr))
195 printf("....Name %s nicht vorhanden", clrip);
198 act->next = act->next->next;
199 act->next->prev = act;
204 int list_not_in( char name[16]) {
208 while ((test != tail) && (i==listTrue)) {
209 i = (strcmp(test->ipadr, name) ? listTrue : listFalse);
211 if (verbose != 0) printf("list_not_in : %d\n",i);
216 void fgd_print_Mat4( const sgMat4 m ) {
217 printf("0.0 %f 0.1 %f 0.2 %f 0.3 %f\n",
218 m[0][0], m[0][1], m[0][2], m[0][3] );
219 printf("1.0 %f 1.1 %f 1.2 %f 1.3 %f\n",
220 m[1][0], m[1][1], m[1][2], m[1][3] );
221 printf("2.0 %f 2.1 %f 2.2 %f 2.3 %f\n",
222 m[2][0], m[2][1], m[2][2], m[2][3] );
223 printf("3.0 %f 3.1 %f 3.2 %f 3.3 %f\n",
224 m[3][0], m[3][1], m[3][2], m[3][3] );
229 /* Let's init a few things */
230 printf("MCP: Allocating memory...");
231 buffp = (char *) malloc(1024); /* No I don't check if there are another KB */
232 fgd_job = (char *) malloc(8);
233 fgd_host = (char *) malloc(64);
234 fgd_callsign = (char *) malloc(64);
235 fgd_name = (char*) malloc(64);
236 fgd_ip = (char *) malloc(16);
237 fgd_mcp_ip = (char *) malloc(16);
238 fgfs_host = (char *) malloc(64);
239 fgfs_pilot = (char *) malloc(64);
240 src_host = (char *) malloc(64);
241 fgd_txt = (char *) malloc(1024);
242 printf("ok\nMCP: Initializing values...");
243 strcpy( fgd_job, "xxx");
244 strcpy( fgd_host, "Olk");
245 strcpy( fgd_callsign, "Unknown");
246 strcpy( fgd_name, "Unknown");
247 strcpy( fgd_ip, (char *) inet_ntoa(address.sin_addr));
248 strcpy( fgd_txt, "");
253 boss->speedf = 100.95;
256 boss->yawf = 456.789;
258 bzero((char *)&address, sizeof(address));
259 address.sin_family = AF_INET;
260 /* determinating the source/sending host */
261 if (uname(&myname) == 0) strcpy(src_host , myname.nodename);
262 printf("MCP: I'm running on HOST : %s ", src_host);
263 if ( (host_info = gethostbyname( src_host)) != NULL ) {
264 bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
265 strcpy((char *) fgd_mcp_ip, (char *) inet_ntoa(address.sin_addr));
267 printf("IP : %s\n", fgd_mcp_ip);
268 FGFS_host = src_host;
269 /* resolving the destination host, here fgd's host */
270 if (verbose == 2) printf(" Resolving default DEAMON: %s ->", fgd_host);
271 if ( (host_info = gethostbyname( fgd_host)) != NULL ) {
272 bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
273 strcpy((char *) fgd_ip, (char *) inet_ntoa(address.sin_addr));
275 printf(" resolved\n FGD running on HOST : %s", fgd_host);
276 printf(" IP : %s\n", fgd_ip);
278 } else if ((address.sin_addr.s_addr = inet_addr( fgd_host)) == INADDR_NONE) {
279 fprintf(stderr," Could not get %s host entry !\n", fgd_host);
280 printf(" NOT resolved !!!\n");
282 } else if (verbose == 2) printf(" address valid\n");
284 if ((base_port > end_port) || ((short)base_port < 0)) {
285 fprintf(stderr,"Bad port range : start=%d end=%d !\n",base_port,end_port);
287 } else if (verbose == 2) {
288 printf(" Port range: %d to %d\n",base_port,end_port);
292 int net_resolv_fgd( char *fgd_host_check ) {
294 char *fgd_ip_check = "";
296 /* resolving the destination host, here fgd's host */
298 if (verbose == 2) printf(" Resolving default DEAMON: %s ->", fgd_host_check);
299 if ( (host_info = gethostbyname( fgd_host_check)) != NULL ) {
300 bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
301 strcpy((char *) fgd_ip_check, (char *) inet_ntoa(address.sin_addr));
302 fgd_ip = fgd_ip_check;
304 printf(" FGD: resolved\nFGD: running on HOST : %s", fgd_host_check);
305 printf(" IP : %s\n", fgd_ip_check);
306 strcpy( fgd_host, fgd_host_check);
309 } else if ((address.sin_addr.s_addr = inet_addr( fgd_host)) == INADDR_NONE) {
310 fprintf(stderr,"FGD: Could not get %s host entry !\n", fgd_host_check);
311 printf(" FGD: NOT resolved !!!\n");
315 } else if (verbose == 2) printf(" address valid\n");
317 if ((base_port > end_port) || ((short)base_port < 0)) {
318 fprintf(stderr,"Bad port range : start=%d end=%d !\n",base_port,end_port);
322 } else if (verbose == 2) {
323 printf(" Port range: %d to %d\n",base_port,end_port);
329 void fgd_send_com( char *FGD_com, char *FGFS_host) {
332 // current_port = base_port;
333 if (verbose == 2) printf(" Sending : %s\n", FGD_com);
334 // while (current_port <= end_port) {
335 /* fprintf(stderr,"Trying port: %d\n",current_port); */
336 sock = socket(PF_INET, SOCK_STREAM, 0);
339 // fprintf(stderr, "Error assigning master socket: %s\n",sys_errlist[errno]);
340 fprintf(stderr, "Error assigning master socket: %s\n",
342 /* must check how severe this really is */
346 address.sin_port = htons(current_port);
347 if (verbose == 2) printf(" address.sin_port : %d\n",htons(address.sin_port));
349 f_host_info = gethostbyname(src_host);
351 //printf ("src_host : %s", ntohs(f_host_info->h_addr));
353 if (connect(sock, (struct sockaddr *)&address, sizeof(address)) == 0) {
354 /* FIXME: make a single string instead of sending elements */
356 fgd_len_msg = (int) sizeof(f_host_info->h_addr);
357 /* send length of sender-ip */
358 write( sock, &fgd_len_msg,1);
360 write( sock, f_host_info->h_addr, fgd_len_msg);
362 write( sock, FGD_com, 1);
363 /* send length of dummy-string, for the moment with _WHO_ to execute commando
364 here: his length of ip */
365 f_host_info = gethostbyname(FGFS_host);
366 fgd_len_msg = (int) sizeof(f_host_info->h_addr);
367 write( sock, &fgd_len_msg,1);
368 /* send dummy-string, for the moment with _WHO_ to execute commando
370 write( sock, f_host_info->h_addr, fgd_len_msg);
373 /* Here we send subsequent data... */
374 switch ( (char) FGD_com[0] - 0x30) {
375 case 5: fgd_len_msg = strlen( net_callsign);
376 write( sock, &fgd_len_msg,1);
377 /* send string, for the moment, here: callsign */
378 write( sock, net_callsign, fgd_len_msg);
379 /* Lon, Lat, Alt, Speed, Roll, Pitch, Yaw
380 hope this sprintf call is not too expensive */
381 sprintf( fgd_txt, " %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f",
382 // boss->latf, boss->lonf, boss->altf, boss->speedf,
383 // boss->rollf, boss->pitchf, boss->yawf);
385 Must decide if it's better to send values "as are" or convert them for
386 deamon, better is to let deamon make the job. Anyway this will depend on
387 speed loss/gain in network-area...
389 get_latitude(), get_longitude(), get_altitude(),
390 get_speed(), get_roll()*SGD_RADIANS_TO_DEGREES,
391 get_pitch()*SGD_RADIANS_TO_DEGREES, get_heading());
392 write( sock, fgd_txt, 56);
395 /* Here sending the previously calculated view.Mat4 by FGFS */
396 case 17: if (verbose == 2) printf("Checkpoint\n");
397 sgCopyMat4(sgFGD_COORD, globals->get_current_view()->get_VIEW());
400 printf("current_view\n");
401 fgd_print_Mat4( globals->get_current_view()->get_VIEW());
402 printf("FGD_COORD\n");
403 fgd_print_Mat4( sgFGD_COORD);
405 fgd_len_msg = strlen( net_callsign);
406 write( sock, &fgd_len_msg,1);
407 /* send string, for the moment, here: callsign */
408 write( sock, net_callsign, fgd_len_msg);
409 /* MATRIX-variant of Lon, Lat etc...
410 hope this sprintf call is not too expensive */
411 fgd_len_msg = sprintf( fgd_txt, " %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
412 sgFGD_COORD[0][0], sgFGD_COORD[0][1], sgFGD_COORD[0][2], sgFGD_COORD[0][3],
413 sgFGD_COORD[1][0], sgFGD_COORD[1][1], sgFGD_COORD[1][2], sgFGD_COORD[1][3],
414 sgFGD_COORD[2][0], sgFGD_COORD[2][1], sgFGD_COORD[2][2], sgFGD_COORD[2][3],
415 sgFGD_COORD[3][0], sgFGD_COORD[3][1], sgFGD_COORD[3][2], sgFGD_COORD[3][3]);
416 fgd_txt[fgd_len_msg] = 0;
417 write( sock, fgd_txt, fgd_len_msg+1);
423 /* be verbose, this goes later into own (*void) */
424 if (verbose == 2) printf(" Message : %s\n", FGD_com);
426 case 0: // printf("%d\n",current_port);
428 case 1: service_info = getservbyport(htons(current_port),"tcp");
430 printf("%d -> service name unknown\n",current_port);
432 printf("%d -> %s\n",current_port,service_info->s_name);
435 case 2: service_info = getservbyport(htons(current_port),"tcp");
437 printf(" Port %d found. Service name unknown\n",current_port);
439 printf(" Port %d found. Service name: %s\n",current_port,service_info->s_name);
443 } else if (errno == 113) {
444 fprintf(stderr,"No route to host !\n");
445 /* must check this */
448 /* fprintf(stderr,"Error %d connecting socket %d to port %d: %s\n",
449 errno,sock,current_port,sys_errlist[errno]); */
451 // service_info = getservbyport(htons(current_port),"tcp");
452 // if (!service_info) {
456 /* The Receiving Part, fgd returns errormessages, succes, etc... */
458 fgd_status = recv( sock, (char *) buffp, 5, MSG_WAITALL);
459 if (verbose == 2) printf(" status %d\n", fgd_status);
461 // while ( (fgd_status != 5) && (fgd_status != 0) );
462 while ( (fgd_status == -1) || (fgd_status == -1) );
463 fgd_reply_len = (unsigned char) buffp[3] + (unsigned char) buffp[4] * 256;
465 printf(" Got reply : %x %x %x MSG length %d Bytes\n",
466 buffp[0], buffp[1], buffp[2], fgd_reply_len);
468 if (strncmp( buffp, "FGD", 3) == 0) {
469 switch ( (char) FGD_com[0] - 0x30) {
471 abc = read( sock, fgd_name, fgd_reply_len);
472 if (verbose == 2) printf("readwert: %d", abc);
473 // fgd_name[buffp[3]] = 0;
474 printf("FGD: FlightGear-Deamon %s detected\n", fgd_name);
476 case 1: read( sock, fgd_txt, fgd_reply_len);
477 printf("FGD: Registering Host %s\n", fgd_txt);
479 case 2: printf("FGD: Showing registered Hosts at %s\n", fgd_host);
480 if ( fgd_reply_len != 5) {
481 /* FIXME: replace with SELECT to avoid broken pipes, known bug (-; */
483 fgd_status = recv( sock, fgd_txt, fgd_reply_len - 5,
485 // printf(" status %d\n", fgd_status);
487 // while ( (fgd_status != 5) && (fgd_status != 0) );
488 while ( (fgd_status == -1) || (fgd_status == -1) );
489 // read( sock, fgd_txt, fgd_reply_len - 5);
491 for (fgd_cnt = 1; fgd_cnt < (fgd_txt[0]+1); fgd_cnt++) {
492 fgd_ele_len = fgd_txt[fgd_curpos];
493 bcopy( &fgd_txt[fgd_curpos], fgfs_host, fgd_ele_len);
494 // fgfs_host[fgd_ele_len] = 0;
495 fgd_curpos += fgd_ele_len + 1;
496 if (verbose == 2) printf(" #%d %s\n", fgd_cnt, fgfs_host);
500 case 5: printf("FGD: Receiving data from Host %s\n", FGFS_host);
501 read( sock, fgd_txt, buffp[3]);
502 fgd_txt[buffp[3]] = 0;
504 if (strcmp(fgd_txt, "UNKNOWN") == 0) {
505 printf("FGD: Host not in list, sorry...\n");
507 else printf("FGD: Data from Host %s received\n", fgd_txt);
509 /* This has problem with glibc-2.1
510 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
511 if (verbose == 2) printf("FGD: Data from Host %s received\n", fgd_txt);
513 else if (verbose == 2) printf("FGD: Host not in list, sorry...\n");
516 case 17: if (verbose == 2) printf("FGD: Receiving Mat4 data from Host %s\n", FGFS_host);
517 read( sock, fgd_txt, fgd_reply_len);
518 // fgd_txt[buffp[3]] = 0;
519 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
520 if (verbose == 2) printf("FGD: Mat4 Data from Host %s received\n", fgd_txt);
522 else printf("FGD: Host not in list, sorry...\n");
524 case 6: printf("FGD: Sending data to Host %s\n", FGFS_host);
526 /* FIXME: replace with SELECT */
527 if (verbose == 2) printf("Noch %d bytes\n", (unsigned char) buffp[3]);
529 fgd_status = recv( sock, fgd_txt, (unsigned char) buffp[3]-4, MSG_PEEK);
530 if (verbose == 2) printf("Status %d\n", fgd_status);
532 while ( (fgd_status == 4) || (fgd_status == -1) );
533 // while ( (fgd_status == -1) || (fgd_status == -1) );
534 read( sock, fgd_txt, buffp[3]-4);
536 fgd_ppl_old = fgd_ppl;
537 fgd_ppl = fgd_txt[0];
538 /* Check if list has changed (pilot joined/left) */
539 if (fgd_ppl != fgd_ppl_old) {
540 printf(" List changed!!!\n");
541 for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
542 if (verbose == 2) printf(" Checkpoint\n");
543 incoming = head->next;
544 if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
546 printf(" Clearing entry.\n");
547 list_clear(incoming->ipadr);
552 incoming = head->next;
553 for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
555 fgd_ele_len = fgd_txt[fgd_curpos-1];
556 bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
557 incoming->ipadr[fgd_ele_len] = 0;
558 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
560 fgd_ele_len = fgd_txt[fgd_curpos-1];
561 bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
562 incoming->callsign[fgd_ele_len] = 0;
563 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
566 printf(" #%d %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
567 printf(" curpos:%d\n", fgd_curpos);
568 sscanf( &fgd_txt[fgd_curpos]," %7f %7f %7f %7f %7f %7f %7f",
569 &incoming->latf, &incoming->lonf,
570 &incoming->altf, &incoming->speedf, &incoming->rollf,
571 &incoming->pitchf, &incoming->yawf);
572 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",
573 incoming->latf, incoming->lonf, incoming->altf, incoming->speedf,
574 incoming->rollf, incoming->pitchf, incoming->yawf);
577 incoming = incoming->next;
580 } /* end if "data available" */
581 /* Here reading the answer of completed command by fgd */
582 /* read( sock, fgd_txt, buffp[3]);
583 fgd_txt[buffp[3]] = 0;
584 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
585 if (verbose == 2) printf("FGD: Data to Host sent\n");
587 else printf("FGD: Host not in list, sorry...\n");
590 case 18: if (verbose == 2) printf("FGD: Sending Mat4 data to Host %s\n", FGFS_host);
591 if (fgd_reply_len != 5) {
592 /* FIXME: replace with SELECT */
593 if (verbose == 2) printf("Noch %d bytes\n", fgd_reply_len);
595 fgd_status = recv( sock, fgd_txt, fgd_reply_len - 5, MSG_WAITALL);
596 if (verbose == 2) printf("Status %d\n", fgd_status);
598 // while ( (fgd_status == 4) || (fgd_status == -1) );
599 while ( (fgd_status == -1) || (fgd_status == -1) );
600 // read( sock, fgd_txt, fgd_reply_len - 5);
602 fgd_ppl_old = fgd_ppl;
603 fgd_ppl = fgd_txt[0];
604 /* Check if list has changed (pilot joined/left) */
605 if (fgd_ppl != fgd_ppl_old) {
606 printf(" List changed!!!\n");
607 for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
608 if (verbose == 2) printf(" Checkpoint\n");
609 incoming = head->next;
610 if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
612 printf(" Clearing entry.\n");
613 list_clear(incoming->ipadr);
618 incoming = head->next;
619 for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
621 fgd_ele_len = fgd_txt[fgd_curpos-1];
622 bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
623 incoming->ipadr[fgd_ele_len] = 0;
624 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
626 fgd_ele_len = fgd_txt[fgd_curpos-1];
627 bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
628 incoming->callsign[fgd_ele_len] = 0;
629 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
632 printf(" #%d %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
633 printf(" curpos:%d\n", fgd_curpos);
635 fgd_len_msg = strlen ( &fgd_txt[fgd_curpos]);
636 sscanf( &fgd_txt[fgd_curpos]," %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
637 &incoming->sgFGD_COORD[0][0], &incoming->sgFGD_COORD[0][1], &incoming->sgFGD_COORD[0][2], &incoming->sgFGD_COORD[0][3],
638 &incoming->sgFGD_COORD[1][0], &incoming->sgFGD_COORD[1][1], &incoming->sgFGD_COORD[1][2], &incoming->sgFGD_COORD[1][3],
639 &incoming->sgFGD_COORD[2][0], &incoming->sgFGD_COORD[2][1], &incoming->sgFGD_COORD[2][2], &incoming->sgFGD_COORD[2][3],
640 &incoming->sgFGD_COORD[3][0], &incoming->sgFGD_COORD[3][1], &incoming->sgFGD_COORD[3][2], &incoming->sgFGD_COORD[3][3]);
643 printf("Incoming Mat4\n");
644 fgd_print_Mat4( incoming->sgFGD_COORD );
646 fgd_curpos += fgd_len_msg + 2;
647 incoming = incoming->next;
650 } /* end if "data available" */
651 /* The first view-Mat4 is somebody else */
652 sgCopyMat4(sgFGD_VIEW, head->next->sgFGD_COORD);
654 /* Here reading the answer of completed command by fgd */
655 /* read( sock, fgd_txt, buffp[3]);
656 // fgd_txt[buffp[3]] = 0;
657 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
658 if (verbose == 2) printf("FGD: Mat4 Data to Host sent\n");
660 else printf("FGD: Host not in list, sorry...\n");
663 case 8: printf("FGD: Unregistering Host %s\n", FGFS_host);
664 read( sock, fgd_txt, buffp[3]);
665 fgd_txt[buffp[3]] = 0;
667 while (test != tail) {
668 list_clear( test->ipadr );
673 if (strcmp(fgd_txt, "UNKNOWN") == 0) {
674 printf("FGD: Host not in list, sorry...\n");
676 else printf("FGD: Host %s unregistered\n", fgd_txt);
678 /* This does not work on glibc-2.1
679 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
680 printf("FGD: Host %s unregistered\n", fgd_txt);
682 else printf("FGD: Host not in list, sorry...\n");
685 case 9: printf(" Shutdown FlightGear-Deamon %s .\n", fgd_name);
689 } else printf(" Huh?: no deamon present, yuk!!!\n");
695 if (verbose == 2) printf("fgd_com completed.\n");