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>
48 #include <arpa/inet.h>
51 struct sockaddr_in address;
52 struct sockaddr_in my_address;
55 //#if defined( __CYGWIN__ )
57 //const char *const *sys_errlist = _sys_errlist;
60 //extern const char *const sys_errlist[];
63 //#if defined( __CYGWIN__ )
69 //extern const char *const sys_errlist[];
71 int current_port = 10000;
72 u_short base_port = 10000;
73 u_short end_port = 10010;
75 struct hostent *host_info, *f_host_info;
76 struct servent *service_info;
77 struct utsname myname;
81 int fgd_len_msg = 1, fgd_reply_len, fgd_status, fgd_ele_len, fgd_curpos, fgd_cnt, fgd_ppl,
82 fgd_ppl_old, fgd_loss, net_r;
84 char *fgd_job, *fgd_callsign, *fgd_name, *fgd_ip, *fgd_mcp_ip;
85 char *buffp, *src_host, *fgd_host, *fgfs_host, *fgfs_pilot, *fgd_txt;
87 extern sgMat4 sgFGD_VIEW;
88 extern ssgRoot *fgd_scene;
89 extern char *FGFS_host, *net_callsign;
93 const int listTrue = 0;
94 const int listFalse= -1;
97 /* unsigned */ char ipadr[16], callsign[16];
98 /* unsigned */ char lon[8], lat[8], alt[8], roll[8], pitch[8], yaw[8];
99 float lonf, latf, altf, speedf, rollf, pitchf, yawf;
101 ssgSelector *fgd_sel;
102 ssgTransform *fgd_pos;
103 struct list_ele *next, *prev;
106 struct list_ele *head, *tail, *act, *test, *incoming, *boss, *other; /* fgd_msg; */
108 /*...Create head and tail of list */
109 void list_init( void) {
111 incoming = (struct list_ele*) malloc(sizeof(struct list_ele));
112 boss = (struct list_ele*) malloc(sizeof(struct list_ele));
113 other = (struct list_ele*) malloc(sizeof(struct list_ele));
114 head = (struct list_ele*) malloc(sizeof(struct list_ele));
115 tail = (struct list_ele*) malloc(sizeof(struct list_ele));
116 if (head == NULL || tail == NULL) { printf("Out of memory\n"); exit(1); }
118 tail->ipadr[0] = 255;
120 head->prev = tail->prev = head;
121 head->next = tail->next = tail;
122 act = head; /* put listpointer to beginning of list */
125 void list_output( void) {
128 void list_search( char name[16]) {
130 if (strcmp(name, head->next->ipadr) <= 0) act = head;
131 else if (strcmp(name, tail->prev->ipadr) > 0) act = tail->prev;
133 int vergleich = strcmp(name, act->ipadr);
135 while (strcmp(name, act->next->ipadr) > 0) {
138 else if (vergleich < 0)
139 while (strcmp(name, act->ipadr) < 0) {
143 while (strcmp(name, act->ipadr) == 0) {
149 void list_insert( char newip[16]) {
150 struct list_ele *new_ele;
152 new_ele = (struct list_ele*) malloc(sizeof(struct list_ele));
153 if (new_ele == NULL) { printf("Out of memory\n"); exit(1); }
154 strcpy(new_ele->ipadr, newip);
155 /* setting default */
156 strcpy(new_ele->callsign, "not assigned");
157 /* generating ssg stuff */
158 new_ele->fgd_sel = new ssgSelector;
159 new_ele->fgd_pos = new ssgTransform;
161 ssgEntity *fgd_obj = ssgLoadAC( "tuxcopter.ac" );
162 fgd_obj->clrTraversalMaskBits( SSGTRAV_HOT );
163 new_ele->fgd_pos->addKid( fgd_obj );
164 new_ele->fgd_sel->addKid( new_ele->fgd_pos );
165 ssgFlatten( fgd_obj );
166 ssgStripify( new_ele->fgd_sel );
168 fgd_scene->addKid( new_ele->fgd_sel );
169 fgd_scene->addKid( fgd_obj );
170 /* ssgKid "born" and inserted into scene */
173 new_ele->next = act->next;
174 act->next->prev = act->next = new_ele;
177 void list_setval( char newip[16]) {
180 strcpy( act->next->callsign, incoming->callsign);
181 printf("Callsign %s\n", act->next->callsign);
185 void list_clear( char clrip[16]) {
186 struct list_ele *clr_ele;
189 if ( strcmp( clrip, act->next->ipadr))
190 printf("....Name %s nicht vorhanden", clrip);
193 act->next = act->next->next;
194 act->next->prev = act;
199 int list_not_in( char name[16]) {
203 while ((test != tail) && (i==listTrue)) {
204 i = (strcmp(test->ipadr, name) ? listTrue : listFalse);
206 if (verbose != 0) printf("list_not_in : %d\n",i);
211 void fgd_print_Mat4( const sgMat4 m ) {
212 printf("0.0 %f 0.1 %f 0.2 %f 0.3 %f\n",
213 m[0][0], m[0][1], m[0][2], m[0][3] );
214 printf("1.0 %f 1.1 %f 1.2 %f 1.3 %f\n",
215 m[1][0], m[1][1], m[1][2], m[1][3] );
216 printf("2.0 %f 2.1 %f 2.2 %f 2.3 %f\n",
217 m[2][0], m[2][1], m[2][2], m[2][3] );
218 printf("3.0 %f 3.1 %f 3.2 %f 3.3 %f\n",
219 m[3][0], m[3][1], m[3][2], m[3][3] );
224 /* Let's init a few things */
225 printf("MCP: Allocating memory...");
226 buffp = (char *) malloc(1024); /* No I don't check if there are another KB */
227 fgd_job = (char *) malloc(8);
228 fgd_host = (char *) malloc(64);
229 fgd_callsign = (char *) malloc(64);
230 fgd_name = (char*) malloc(64);
231 fgd_ip = (char *) malloc(16);
232 fgd_mcp_ip = (char *) malloc(16);
233 fgfs_host = (char *) malloc(64);
234 fgfs_pilot = (char *) malloc(64);
235 src_host = (char *) malloc(64);
236 fgd_txt = (char *) malloc(1024);
237 printf("ok\nMCP: Initializing values...");
238 strcpy( fgd_job, "xxx");
239 strcpy( fgd_host, "Olk");
240 strcpy( fgd_callsign, "Unknown");
241 strcpy( fgd_name, "Unknown");
242 strcpy( fgd_ip, (char *) inet_ntoa(address.sin_addr));
243 strcpy( fgd_txt, "");
248 boss->speedf = 100.95;
251 boss->yawf = 456.789;
253 bzero((char *)&address, sizeof(address));
254 address.sin_family = AF_INET;
255 /* determinating the source/sending host */
256 if (uname(&myname) == 0) strcpy(src_host , myname.nodename);
257 printf("MCP: I'm running on HOST : %s ", src_host);
258 if (host_info = gethostbyname( src_host)) {
259 bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
260 strcpy((char *) fgd_mcp_ip, (char *) inet_ntoa(address.sin_addr));
262 printf("IP : %s\n", fgd_mcp_ip);
263 FGFS_host = src_host;
264 /* resolving the destination host, here fgd's host */
265 if (verbose == 2) printf(" Resolving default DEAMON: %s ->", fgd_host);
266 if (host_info = gethostbyname( fgd_host)) {
267 bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
268 strcpy((char *) fgd_ip, (char *) inet_ntoa(address.sin_addr));
270 printf(" resolved\n FGD running on HOST : %s", fgd_host);
271 printf(" IP : %s\n", fgd_ip);
273 } else if ((address.sin_addr.s_addr = inet_addr( fgd_host)) == INADDR_NONE) {
274 fprintf(stderr," Could not get %s host entry !\n", fgd_host);
275 printf(" NOT resolved !!!\n");
277 } else if (verbose == 2) printf(" address valid\n");
279 if ((base_port > end_port) || ((short)base_port < 0)) {
280 fprintf(stderr,"Bad port range : start=%d end=%d !\n",base_port,end_port);
282 } else if (verbose == 2) {
283 printf(" Port range: %d to %d\n",base_port,end_port);
287 int net_resolv_fgd( char *fgd_host_check ) {
289 char *fgd_ip_check = "";
291 /* resolving the destination host, here fgd's host */
293 if (verbose == 2) printf(" Resolving default DEAMON: %s ->", fgd_host_check);
294 if (host_info = gethostbyname( fgd_host_check)) {
295 bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
296 strcpy((char *) fgd_ip_check, (char *) inet_ntoa(address.sin_addr));
297 fgd_ip = fgd_ip_check;
299 printf(" FGD: resolved\nFGD: running on HOST : %s", fgd_host_check);
300 printf(" IP : %s\n", fgd_ip_check);
301 strcpy( fgd_host, fgd_host_check);
304 } else if ((address.sin_addr.s_addr = inet_addr( fgd_host)) == INADDR_NONE) {
305 fprintf(stderr,"FGD: Could not get %s host entry !\n", fgd_host_check);
306 printf(" FGD: NOT resolved !!!\n");
310 } else if (verbose == 2) printf(" address valid\n");
312 if ((base_port > end_port) || ((short)base_port < 0)) {
313 fprintf(stderr,"Bad port range : start=%d end=%d !\n",base_port,end_port);
317 } else if (verbose == 2) {
318 printf(" Port range: %d to %d\n",base_port,end_port);
324 void fgd_send_com( char *FGD_com, char *FGFS_host) {
327 // current_port = base_port;
328 if (verbose == 2) printf(" Sending : %s\n", FGD_com);
329 // while (current_port <= end_port) {
330 /* fprintf(stderr,"Trying port: %d\n",current_port); */
331 sock = socket(PF_INET, SOCK_STREAM, 0);
334 // fprintf(stderr, "Error assigning master socket: %s\n",sys_errlist[errno]);
335 fprintf(stderr, "Error assigning master socket: %s\n",
337 /* must check how severe this really is */
341 address.sin_port = htons(current_port);
342 if (verbose == 2) printf(" address.sin_port : %d\n",htons(address.sin_port));
344 f_host_info = gethostbyname(src_host);
346 //printf ("src_host : %s", ntohs(f_host_info->h_addr));
348 if (connect(sock, (struct sockaddr *)&address, sizeof(address)) == 0) {
349 /* FIXME: make a single string instead of sending elements */
351 fgd_len_msg = (int) sizeof(f_host_info->h_addr);
352 /* send length of sender-ip */
353 write( sock, &fgd_len_msg,1);
355 write( sock, f_host_info->h_addr, fgd_len_msg);
357 write( sock, FGD_com, 1);
358 /* send length of dummy-string, for the moment with _WHO_ to execute commando
359 here: his length of ip */
360 f_host_info = gethostbyname(FGFS_host);
361 fgd_len_msg = (int) sizeof(f_host_info->h_addr);
362 write( sock, &fgd_len_msg,1);
363 /* send dummy-string, for the moment with _WHO_ to execute commando
365 write( sock, f_host_info->h_addr, fgd_len_msg);
368 /* Here we send subsequent data... */
369 switch ( (char) FGD_com[0] - 0x30) {
370 case 5: fgd_len_msg = strlen( net_callsign);
371 write( sock, &fgd_len_msg,1);
372 /* send string, for the moment, here: callsign */
373 write( sock, net_callsign, fgd_len_msg);
374 /* Lon, Lat, Alt, Speed, Roll, Pitch, Yaw
375 hope this sprintf call is not too expensive */
376 sprintf( fgd_txt, " %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f",
377 // boss->latf, boss->lonf, boss->altf, boss->speedf,
378 // boss->rollf, boss->pitchf, boss->yawf);
380 Must decide if it's better to send values "as are" or convert them for
381 deamon, better is to let deamon make the job. Anyway this will depend on
382 speed loss/gain in network-area...
384 get_latitude(), get_longitude(), get_altitude(),
385 get_speed(), get_roll()*SGD_RADIANS_TO_DEGREES,
386 get_pitch()*SGD_RADIANS_TO_DEGREES, get_heading());
387 write( sock, fgd_txt, 56);
390 /* Here sending the previously calculated view.Mat4 by FGFS */
391 case 17: if (verbose == 2) printf("Checkpoint\n");
392 sgCopyMat4(sgFGD_COORD, globals->get_current_view()->get_VIEW());
395 printf("current_view\n");
396 fgd_print_Mat4( globals->get_current_view()->get_VIEW());
397 printf("FGD_COORD\n");
398 fgd_print_Mat4( sgFGD_COORD);
400 fgd_len_msg = strlen( net_callsign);
401 write( sock, &fgd_len_msg,1);
402 /* send string, for the moment, here: callsign */
403 write( sock, net_callsign, fgd_len_msg);
404 /* MATRIX-variant of Lon, Lat etc...
405 hope this sprintf call is not too expensive */
406 fgd_len_msg = sprintf( fgd_txt, " %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
407 sgFGD_COORD[0][0], sgFGD_COORD[0][1], sgFGD_COORD[0][2], sgFGD_COORD[0][3],
408 sgFGD_COORD[1][0], sgFGD_COORD[1][1], sgFGD_COORD[1][2], sgFGD_COORD[1][3],
409 sgFGD_COORD[2][0], sgFGD_COORD[2][1], sgFGD_COORD[2][2], sgFGD_COORD[2][3],
410 sgFGD_COORD[3][0], sgFGD_COORD[3][1], sgFGD_COORD[3][2], sgFGD_COORD[3][3]);
411 fgd_txt[fgd_len_msg] = 0;
412 write( sock, fgd_txt, fgd_len_msg+1);
418 /* be verbose, this goes later into own (*void) */
419 if (verbose == 2) printf(" Message : %s\n", FGD_com);
421 case 0: // printf("%d\n",current_port);
423 case 1: service_info = getservbyport(htons(current_port),"tcp");
425 printf("%d -> service name unknown\n",current_port);
427 printf("%d -> %s\n",current_port,service_info->s_name);
430 case 2: service_info = getservbyport(htons(current_port),"tcp");
432 printf(" Port %d found. Service name unknown\n",current_port);
434 printf(" Port %d found. Service name: %s\n",current_port,service_info->s_name);
438 } else if (errno == 113) {
439 fprintf(stderr,"No route to host !\n");
440 /* must check this */
443 /* fprintf(stderr,"Error %d connecting socket %d to port %d: %s\n",
444 errno,sock,current_port,sys_errlist[errno]); */
446 // service_info = getservbyport(htons(current_port),"tcp");
447 // if (!service_info) {
451 /* The Receiving Part, fgd returns errormessages, succes, etc... */
453 fgd_status = recv( sock, (char *) buffp, 5, MSG_WAITALL);
454 if (verbose == 2) printf(" status %d\n", fgd_status);
456 // while ( (fgd_status != 5) && (fgd_status != 0) );
457 while ( (fgd_status == -1) || (fgd_status == -1) );
458 fgd_reply_len = (unsigned char) buffp[3] + (unsigned char) buffp[4] * 256;
460 printf(" Got reply : %x %x %x MSG length %d Bytes\n",
461 buffp[0], buffp[1], buffp[2], fgd_reply_len);
463 if (strncmp( buffp, "FGD", 3) == 0) {
464 switch ( (char) FGD_com[0] - 0x30) {
466 abc = read( sock, fgd_name, fgd_reply_len);
467 if (verbose == 2) printf("readwert: %d", abc);
468 // fgd_name[buffp[3]] = 0;
469 printf("FGD: FlightGear-Deamon %s detected\n", fgd_name);
471 case 1: read( sock, fgd_txt, fgd_reply_len);
472 printf("FGD: Registering Host %s\n", fgd_txt);
474 case 2: printf("FGD: Showing registered Hosts at %s\n", fgd_host);
475 if ( fgd_reply_len != 5) {
476 /* FIXME: replace with SELECT to avoid broken pipes, known bug (-; */
478 fgd_status = recv( sock, fgd_txt, fgd_reply_len - 5,
480 // printf(" status %d\n", fgd_status);
482 // while ( (fgd_status != 5) && (fgd_status != 0) );
483 while ( (fgd_status == -1) || (fgd_status == -1) );
484 // read( sock, fgd_txt, fgd_reply_len - 5);
486 for (fgd_cnt = 1; fgd_cnt < (fgd_txt[0]+1); fgd_cnt++) {
487 fgd_ele_len = fgd_txt[fgd_curpos];
488 bcopy( &fgd_txt[fgd_curpos], fgfs_host, fgd_ele_len);
489 // fgfs_host[fgd_ele_len] = 0;
490 fgd_curpos += fgd_ele_len + 1;
491 if (verbose == 2) printf(" #%d %s\n", fgd_cnt, fgfs_host);
495 case 5: printf("FGD: Receiving data from Host %s\n", FGFS_host);
496 read( sock, fgd_txt, buffp[3]);
497 fgd_txt[buffp[3]] = 0;
499 if (strcmp(fgd_txt, "UNKNOWN") == 0) {
500 printf("FGD: Host not in list, sorry...\n");
502 else printf("FGD: Data from Host %s received\n", fgd_txt);
504 /* This has problem with glibc-2.1
505 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
506 if (verbose == 2) printf("FGD: Data from Host %s received\n", fgd_txt);
508 else if (verbose == 2) printf("FGD: Host not in list, sorry...\n");
511 case 17: if (verbose == 2) printf("FGD: Receiving Mat4 data from Host %s\n", FGFS_host);
512 read( sock, fgd_txt, fgd_reply_len);
513 // fgd_txt[buffp[3]] = 0;
514 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
515 if (verbose == 2) printf("FGD: Mat4 Data from Host %s received\n", fgd_txt);
517 else printf("FGD: Host not in list, sorry...\n");
519 case 6: printf("FGD: Sending data to Host %s\n", FGFS_host);
521 /* FIXME: replace with SELECT */
522 if (verbose == 2) printf("Noch %d bytes\n", (unsigned char) buffp[3]);
524 fgd_status = recv( sock, fgd_txt, (unsigned char) buffp[3]-4, MSG_PEEK);
525 if (verbose == 2) printf("Status %d\n", fgd_status);
527 while ( (fgd_status == 4) || (fgd_status == -1) );
528 // while ( (fgd_status == -1) || (fgd_status == -1) );
529 read( sock, fgd_txt, buffp[3]-4);
531 fgd_ppl_old = fgd_ppl;
532 fgd_ppl = fgd_txt[0];
533 /* Check if list has changed (pilot joined/left) */
534 if (fgd_ppl != fgd_ppl_old) {
535 printf(" List changed!!!\n");
536 for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
537 if (verbose == 2) printf(" Checkpoint\n");
538 incoming = head->next;
539 if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
541 printf(" Clearing entry.\n");
542 list_clear(incoming->ipadr);
547 incoming = head->next;
548 for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
550 fgd_ele_len = fgd_txt[fgd_curpos-1];
551 bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
552 incoming->ipadr[fgd_ele_len] = 0;
553 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
555 fgd_ele_len = fgd_txt[fgd_curpos-1];
556 bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
557 incoming->callsign[fgd_ele_len] = 0;
558 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
561 printf(" #%d %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
562 printf(" curpos:%d\n", fgd_curpos);
563 sscanf( &fgd_txt[fgd_curpos]," %7f %7f %7f %7f %7f %7f %7f",
564 &incoming->latf, &incoming->lonf,
565 &incoming->altf, &incoming->speedf, &incoming->rollf,
566 &incoming->pitchf, &incoming->yawf);
567 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",
568 incoming->latf, incoming->lonf, incoming->altf, incoming->speedf,
569 incoming->rollf, incoming->pitchf, incoming->yawf);
572 incoming = incoming->next;
575 } /* end if "data available" */
576 /* Here reading the answer of completed command by fgd */
577 /* read( sock, fgd_txt, buffp[3]);
578 fgd_txt[buffp[3]] = 0;
579 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
580 if (verbose == 2) printf("FGD: Data to Host sent\n");
582 else printf("FGD: Host not in list, sorry...\n");
585 case 18: if (verbose == 2) printf("FGD: Sending Mat4 data to Host %s\n", FGFS_host);
586 if (fgd_reply_len != 5) {
587 /* FIXME: replace with SELECT */
588 if (verbose == 2) printf("Noch %d bytes\n", fgd_reply_len);
590 fgd_status = recv( sock, fgd_txt, fgd_reply_len - 5, MSG_WAITALL);
591 if (verbose == 2) printf("Status %d\n", fgd_status);
593 // while ( (fgd_status == 4) || (fgd_status == -1) );
594 while ( (fgd_status == -1) || (fgd_status == -1) );
595 // read( sock, fgd_txt, fgd_reply_len - 5);
597 fgd_ppl_old = fgd_ppl;
598 fgd_ppl = fgd_txt[0];
599 /* Check if list has changed (pilot joined/left) */
600 if (fgd_ppl != fgd_ppl_old) {
601 printf(" List changed!!!\n");
602 for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
603 if (verbose == 2) printf(" Checkpoint\n");
604 incoming = head->next;
605 if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
607 printf(" Clearing entry.\n");
608 list_clear(incoming->ipadr);
613 incoming = head->next;
614 for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
616 fgd_ele_len = fgd_txt[fgd_curpos-1];
617 bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
618 incoming->ipadr[fgd_ele_len] = 0;
619 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
621 fgd_ele_len = fgd_txt[fgd_curpos-1];
622 bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
623 incoming->callsign[fgd_ele_len] = 0;
624 fgd_curpos = fgd_curpos + fgd_ele_len + 1;
627 printf(" #%d %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
628 printf(" curpos:%d\n", fgd_curpos);
630 fgd_len_msg = strlen ( &fgd_txt[fgd_curpos]);
631 sscanf( &fgd_txt[fgd_curpos]," %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
632 &incoming->sgFGD_COORD[0][0], &incoming->sgFGD_COORD[0][1], &incoming->sgFGD_COORD[0][2], &incoming->sgFGD_COORD[0][3],
633 &incoming->sgFGD_COORD[1][0], &incoming->sgFGD_COORD[1][1], &incoming->sgFGD_COORD[1][2], &incoming->sgFGD_COORD[1][3],
634 &incoming->sgFGD_COORD[2][0], &incoming->sgFGD_COORD[2][1], &incoming->sgFGD_COORD[2][2], &incoming->sgFGD_COORD[2][3],
635 &incoming->sgFGD_COORD[3][0], &incoming->sgFGD_COORD[3][1], &incoming->sgFGD_COORD[3][2], &incoming->sgFGD_COORD[3][3]);
638 printf("Incoming Mat4\n");
639 fgd_print_Mat4( incoming->sgFGD_COORD );
641 fgd_curpos += fgd_len_msg + 2;
642 incoming = incoming->next;
645 } /* end if "data available" */
646 /* The first view-Mat4 is somebody else */
647 sgCopyMat4(sgFGD_VIEW, head->next->sgFGD_COORD);
649 /* Here reading the answer of completed command by fgd */
650 /* read( sock, fgd_txt, buffp[3]);
651 // fgd_txt[buffp[3]] = 0;
652 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
653 if (verbose == 2) printf("FGD: Mat4 Data to Host sent\n");
655 else printf("FGD: Host not in list, sorry...\n");
658 case 8: printf("FGD: Unregistering Host %s\n", FGFS_host);
659 read( sock, fgd_txt, buffp[3]);
660 fgd_txt[buffp[3]] = 0;
662 while (test != tail) {
663 list_clear( test->ipadr );
668 if (strcmp(fgd_txt, "UNKNOWN") == 0) {
669 printf("FGD: Host not in list, sorry...\n");
671 else printf("FGD: Host %s unregistered\n", fgd_txt);
673 /* This does not work on glibc-2.1
674 if (strcmp(fgd_txt, "UNKNOWN") == -1) {
675 printf("FGD: Host %s unregistered\n", fgd_txt);
677 else printf("FGD: Host not in list, sorry...\n");
680 case 9: printf(" Shutdown FlightGear-Deamon %s .\n", fgd_name);
684 } else printf(" Huh?: no deamon present, yuk!!!\n");
690 if (verbose == 2) printf("fgd_com completed.\n");