]> git.mxchange.org Git - flightgear.git/blob - src/NetworkOLK/net_send.cxx
ab00ff48fed5ff156afc57c775440b399958ad6b
[flightgear.git] / src / NetworkOLK / net_send.cxx
1 /*************************************************************/
2 /* FGD_MCP.C by Oliver Delise                                */
3 /* Contact info:                                             */
4 /* e-mail: delise@mail.isis.de                               */
5 /* www: http://www.isis.de/members/~odelise/progs/mmx-emu/   */
6 /* ftp: http://www.isis.de/members/~odelise/progs/flightgear */
7 /*                                                           */
8 /* Version 0.1-alpha                                         */
9 /* The author of this program offers no waranty at all       */
10 /* about the correct execution of this software material.    */
11 /* Furthermore, the author can NOT be held responsible for   */
12 /* any physical or moral damage caused by the use of this    */
13 /* software.                                                 */
14 /*                                                           */
15 /* This is an interactive standalone Tool to communicate     */ 
16 /* with any FlightGear-Deamon.                               */
17 /* This is Open Source Software with many parts              */
18 /* shamelessly stolen from others...                         */
19 /*                                                           */
20 /* -> This program will use a TCP port listening on a        */
21 /*    remote or local host inside the range you give to it.  */
22 /*    I offer no warranty over the accuracy though :)        */
23 /*    There are 3 verbose modes: No info, service info, and  */
24 /*    full info. No info is good of you only want the list   */
25 /*    of the ports, no more info. The best mode is Full      */
26 /*    info, as you get error information,etc. The main       */
27 /*    output is STDOUT, and ALL the errors go to STDERR.     */
28 /*                                                           */
29 /*    History: v0.1pre-alpha: May 25 1999 -> First release   */
30 /*             v0.1-alpha     Nov 11 1999                    */
31 /*************************************************************/
32
33 #include <stdio.h>
34 #include "fgd.h"
35
36 /* I prefer NHV's decl. */
37 #include <Cockpit/hud.hxx>
38 #include <Include/fg_constants.h>
39 #include <ssg.h>
40 #include <Main/views.hxx>
41
42 //#define printf //
43
44 /* Netstuff */
45 #include <arpa/inet.h>
46 int sock = -1;
47 int my_sock;
48 struct sockaddr_in address;
49 struct sockaddr_in my_address;
50 int result;
51 extern const char *const sys_errlist[];
52 extern int errno;
53 int current_port  = 10000; 
54 u_short base_port = 10000;
55 u_short end_port  = 10010;
56 int verbose = 0;
57 struct hostent *host_info, *f_host_info;
58 struct servent *service_info;
59 struct utsname myname;
60
61 /* Program-stuff */
62 int i, j;
63 int fgd_len_msg = 1, fgd_reply_len, fgd_status, fgd_ele_len, fgd_curpos, fgd_cnt, fgd_ppl,
64     fgd_ppl_old, fgd_loss, net_r;
65 size_t anz;
66 char *fgd_job, *fgd_callsign, *fgd_name, *fgd_ip, *fgd_mcp_ip;
67 char *buffp, *src_host, *fgd_host, *fgfs_host, *fgfs_pilot, *fgd_txt;
68 sgMat4 sgFGD_COORD;
69 extern sgMat4 sgFGD_VIEW;
70 extern ssgRoot *fgd_scene;
71 extern char *FGFS_host, *net_callsign;
72
73 /* List-stuff */
74
75 const int True  = 0;
76 const int False= -1;
77
78 struct list_ele {
79    /* unsigned */ char ipadr[16], callsign[16];
80    /* unsigned */ char lon[8], lat[8], alt[8], roll[8], pitch[8], yaw[8];
81    float lonf, latf, altf, speedf, rollf, pitchf, yawf;
82    sgMat4 sgFGD_COORD;
83    ssgSelector *fgd_sel;
84    ssgTransform *fgd_pos;
85    struct list_ele *next, *prev;
86 };
87
88 struct list_ele *head, *tail, *act, *test, *incoming, *boss, *other;  /* fgd_msg; */
89
90 /*...Create head and tail of list */
91 void list_init( void) {
92
93    incoming = (struct list_ele*) malloc(sizeof(struct list_ele));
94    boss = (struct list_ele*) malloc(sizeof(struct list_ele));
95    other = (struct list_ele*) malloc(sizeof(struct list_ele));
96    head = (struct list_ele*) malloc(sizeof(struct list_ele));
97    tail = (struct list_ele*) malloc(sizeof(struct list_ele));
98    if (head == NULL || tail == NULL) { printf("Out of memory\n"); exit(1); }
99    head->ipadr[0] = 0;
100    tail->ipadr[0] = 255;
101    tail->ipadr[1] = 0;
102    head->prev = tail->prev = head;
103    head->next = tail->next = tail;
104    act = head;          /* put listpointer to beginning of list */
105 }
106
107 void list_output( void) {
108 }
109
110 void list_search( char name[16]) {
111
112    if (strcmp(name, head->next->ipadr) <= 0)     act = head;
113    else if (strcmp(name, tail->prev->ipadr) > 0) act = tail->prev;
114    else {
115       int vergleich = strcmp(name, act->ipadr);
116       if (vergleich > 0)
117          while (strcmp(name, act->next->ipadr) > 0) {
118             act = act->next;
119          }
120       else if (vergleich < 0)
121          while (strcmp(name, act->ipadr) < 0) {
122             act = act->prev;
123          }
124       else
125          while (strcmp(name, act->ipadr) == 0) {
126             act = act->prev;
127          }
128    }
129 }
130
131 void list_insert( char newip[16]) {
132 struct list_ele *new_ele;
133
134    new_ele = (struct list_ele*) malloc(sizeof(struct list_ele));
135    if (new_ele == NULL) { printf("Out of memory\n"); exit(1); }
136    strcpy(new_ele->ipadr, newip);
137 /* setting default */
138    strcpy(new_ele->callsign, "not assigned");
139 /* generating ssg stuff */
140    new_ele->fgd_sel = new ssgSelector;
141    new_ele->fgd_pos = new ssgTransform;
142
143    ssgEntity *fgd_obj = ssgLoadAC( "tuxcopter.ac" );
144    fgd_obj->clrTraversalMaskBits( SSGTRAV_HOT );
145    new_ele->fgd_pos->addKid( fgd_obj );
146    new_ele->fgd_sel->addKid( new_ele->fgd_pos );
147    ssgFlatten( fgd_obj );
148    ssgStripify( new_ele->fgd_sel );
149
150    fgd_scene->addKid( new_ele->fgd_sel );
151    fgd_scene->addKid( fgd_obj );
152 /* ssgKid "born" and inserted into scene */
153    list_search( newip);
154    new_ele->prev = act;
155    new_ele->next = act->next;
156    act->next->prev = act->next = new_ele;
157 }
158
159 void list_setval( char newip[16]) {
160
161    list_search( newip);
162    strcpy( act->next->callsign, incoming->callsign);
163    printf("Callsign %s\n", act->next->callsign);
164    
165 }
166
167 void list_clear( char clrip[16]) {
168 struct list_ele *clr_ele;
169
170    list_search( clrip);
171    if ( strcmp( clrip, act->next->ipadr))
172       printf("....Name %s nicht vorhanden", clrip);
173    else {
174      clr_ele         = act->next;
175      act->next       = act->next->next;
176      act->next->prev = act;
177      free( clr_ele);
178    }
179 }
180
181 int list_not_in( char name[16]) {
182    
183    i = True;
184    test = head->next;
185    while ((test != tail) && (i==True)) {
186      i = (strcmp(test->ipadr, name) ? True : False);
187      test = test->next;
188      if (verbose != 0) printf("list_not_in : %d\n",i);
189    }
190    return(i);
191 }
192
193 void fgd_print_Mat4( sgMat4 m ) {
194     printf("0.0 %f 0.1 %f 0.2 %f 0.3 %f\n", 
195     m[0][0], m[0][1], m[0][2], m[0][3] );
196     printf("1.0 %f 1.1 %f 1.2 %f 1.3 %f\n", 
197     m[1][0], m[1][1], m[1][2], m[1][3] );
198     printf("2.0 %f 2.1 %f 2.2 %f 2.3 %f\n", 
199     m[2][0], m[2][1], m[2][2], m[2][3] );
200     printf("3.0 %f 3.1 %f 3.2 %f 3.3 %f\n", 
201     m[3][0], m[3][1], m[3][2], m[3][3] );
202 }
203
204 void fgd_init(void){
205
206 /* Let's init a few things */
207    printf("MCP: Allocating memory...");
208    buffp = (char *) malloc(1024); /* No I don't check if there are another KB */
209    fgd_job = (char *) malloc(8);     
210    fgd_host = (char *) malloc(64);
211    fgd_callsign = (char *) malloc(64);
212    fgd_name = (char*) malloc(64);
213    fgd_ip = (char *) malloc(16);
214    fgd_mcp_ip = (char *) malloc(16);
215    fgfs_host = (char *) malloc(64);
216    fgfs_pilot = (char *) malloc(64);
217    src_host = (char *) malloc(64);
218    fgd_txt = (char *) malloc(1024);
219    printf("ok\nMCP: Initializing values...");   
220    strcpy( fgd_job, "xxx");
221    strcpy( fgd_host, "Olk");
222    strcpy( fgd_callsign, "Unknown");
223    strcpy( fgd_name, "Unknown");
224    strcpy( fgd_ip, (char *) inet_ntoa(address.sin_addr));
225    strcpy( fgd_txt, "");
226    printf("ok\n");
227    boss->latf = 112.3;
228    boss->lonf = 4.5;
229    boss->altf = 0.67;
230    boss->speedf = 100.95;
231    boss->rollf = 89.0;
232    boss->pitchf = 1.23;
233    boss->yawf = 456.789;
234    fgd_ppl = 0;
235    bzero((char *)&address, sizeof(address));
236    address.sin_family = AF_INET;
237 /* determinating the source/sending host */
238    if (uname(&myname) == 0) strcpy(src_host , myname.nodename);   
239    printf("MCP: I'm running on HOST : %s  ", src_host);
240    if (host_info = gethostbyname( src_host)) {
241      bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
242      strcpy((char *) fgd_mcp_ip, (char *) inet_ntoa(address.sin_addr));
243      }
244    printf("IP : %s\n", fgd_mcp_ip);
245    FGFS_host = src_host;
246 /* resolving the destination host, here fgd's host */   
247    if (verbose == 2) printf("     Resolving default DEAMON: %s ->", fgd_host);
248    if (host_info = gethostbyname( fgd_host)) {
249      bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
250      strcpy((char *) fgd_ip, (char *) inet_ntoa(address.sin_addr));
251      if (verbose == 2) {
252             printf(" resolved\n     FGD running on HOST : %s", fgd_host);
253             printf("   IP : %s\n", fgd_ip);
254             }
255    } else if ((address.sin_addr.s_addr = inet_addr( fgd_host)) == INADDR_NONE) {
256             fprintf(stderr,"   Could not get %s host entry !\n", fgd_host);
257             printf(" NOT resolved !!!\n");
258             exit(1);
259           } else if (verbose == 2) printf(" address valid\n");
260    
261    if ((base_port > end_port) || ((short)base_port < 0)) { 
262      fprintf(stderr,"Bad port range : start=%d end=%d !\n");
263      exit(1);
264    } else if (verbose == 2) {
265             printf("     Port range: %d to %d\n",base_port,end_port);
266             }
267 }
268
269 int net_resolv_fgd( char *fgd_host_check ) {
270
271 char *fgd_ip_check;
272
273 /* resolving the destination host, here fgd's host */   
274    net_r = 0;
275    if (verbose == 2) printf("     Resolving default DEAMON: %s ->", fgd_host_check);
276    if (host_info = gethostbyname( fgd_host_check)) {
277      bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
278      strcpy((char *) fgd_ip_check, (char *) inet_ntoa(address.sin_addr));
279      fgd_ip = fgd_ip_check;
280      if (verbose == 0) {
281             printf(" FGD: resolved\nFGD: running on HOST : %s", fgd_host_check);
282             printf("   IP : %s\n", fgd_ip_check);
283             strcpy( fgd_host, fgd_host_check);
284 //            return(0);
285             }
286    } else if ((address.sin_addr.s_addr = inet_addr( fgd_host)) == INADDR_NONE) {
287             fprintf(stderr,"FGD:  Could not get %s host entry !\n", fgd_host_check);
288             printf(" FGD: NOT resolved !!!\n");
289             net_r = -1;
290             return(-1);
291             // exit(1);
292           } else if (verbose == 2) printf(" address valid\n");
293    
294    if ((base_port > end_port) || ((short)base_port < 0)) { 
295      fprintf(stderr,"Bad port range : start=%d end=%d !\n");
296      // exit(1);
297         net_r = -2;
298         return(-2);
299    } else if (verbose == 2) {
300             printf("     Port range: %d to %d\n",base_port,end_port);
301             }
302 }
303
304
305 void fgd_send_com( char *FGD_com, char *FGFS_host) {
306
307    strcpy( buffp, "                ");
308 //   current_port = base_port;
309    if (verbose == 2) printf("     Sending : %s\n", FGD_com);
310 //   while (current_port <= end_port) {
311 /*  fprintf(stderr,"Trying port: %d\n",current_port); */
312     sock = socket(PF_INET, SOCK_STREAM, 0);
313     if (sock == -1)
314      {
315         fprintf(stderr, "Error assigning master socket: %s\n",sys_errlist[errno]);
316         exit(-1);
317      } 
318
319     address.sin_port = htons(current_port);
320     if (verbose == 2) printf("     address.sin_port : %d\n",htons(address.sin_port));
321
322     f_host_info = gethostbyname(src_host);
323
324 //printf ("src_host : %s", ntohs(f_host_info->h_addr));
325     
326     if (connect(sock, (struct sockaddr *)&address, sizeof(address)) == 0) {
327 /* FIXME:    make a single string instead of sending elements */
328
329         fgd_len_msg = (int) sizeof(f_host_info->h_addr);
330 /* send length of sender-ip */
331         write( sock, &fgd_len_msg,1);
332 /* send sender-ip */
333         write( sock, f_host_info->h_addr, fgd_len_msg);
334 /* send commando */     
335         write( sock, FGD_com, 1);
336 /* send length of dummy-string, for the moment with _WHO_ to execute commando 
337    here: his length of ip  */
338         f_host_info = gethostbyname(FGFS_host);
339         fgd_len_msg = (int) sizeof(f_host_info->h_addr);
340         write( sock, &fgd_len_msg,1);
341 /* send dummy-string, for the moment with _WHO_ to execute commando 
342    here: his ip  */   
343         write( sock, f_host_info->h_addr, fgd_len_msg);
344 /* END FIXME  */
345
346 /* Here we send subsequent data... */
347         switch  ( (char) FGD_com[0] - 0x30) {
348         case 5:  fgd_len_msg = strlen( net_callsign);
349                  write( sock, &fgd_len_msg,1);
350         /* send string, for the moment, here: callsign */   
351                  write( sock, net_callsign, fgd_len_msg);
352         /* Lon, Lat, Alt, Speed, Roll, Pitch, Yaw
353            hope this sprintf call is not too expensive */
354                  sprintf( fgd_txt, " %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f", 
355 //                          boss->latf, boss->lonf, boss->altf, boss->speedf,
356 //                          boss->rollf, boss->pitchf, boss->yawf);
357 /* 
358    Must decide if it's better to send values "as are" or convert them for
359    deamon, better is to let deamon make the job. Anyway this will depend on 
360    speed loss/gain in network-area...
361 */
362                           get_latitude(), get_longitude(), get_altitude(),
363                           get_speed(), get_roll()*RAD_TO_DEG,
364                           get_pitch()*RAD_TO_DEG, get_heading());
365                  write( sock, fgd_txt, 56);
366                  break;
367
368 /* Here sending the previously calculated view.Mat4 by FGFS */
369         case 17: if (verbose == 2) printf("Checkpoint\n");
370                  sgCopyMat4(sgFGD_COORD, current_view.VIEW);
371
372                  if (verbose == 2) {
373                     printf("current_view\n");
374                     fgd_print_Mat4( current_view.VIEW);
375                     printf("FGD_COORD\n");
376                     fgd_print_Mat4( sgFGD_COORD);
377                  }
378                  fgd_len_msg = strlen( net_callsign);
379                  write( sock, &fgd_len_msg,1);
380         /* send string, for the moment, here: callsign */   
381                  write( sock, net_callsign, fgd_len_msg);
382         /* MATRIX-variant of Lon, Lat etc...
383            hope this sprintf call is not too expensive */
384                  fgd_len_msg = sprintf( fgd_txt, " %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
385                           sgFGD_COORD[0][0], sgFGD_COORD[0][1], sgFGD_COORD[0][2], sgFGD_COORD[0][3],
386                           sgFGD_COORD[1][0], sgFGD_COORD[1][1], sgFGD_COORD[1][2], sgFGD_COORD[1][3],
387                           sgFGD_COORD[2][0], sgFGD_COORD[2][1], sgFGD_COORD[2][2], sgFGD_COORD[2][3],
388                           sgFGD_COORD[3][0], sgFGD_COORD[3][1], sgFGD_COORD[3][2], sgFGD_COORD[3][3]);
389                  fgd_txt[fgd_len_msg] = 0;
390                  write( sock, fgd_txt, fgd_len_msg+1);
391                  break;
392         default: break;
393         }
394         
395
396 /* be verbose, this goes later into own (*void) */ 
397         if (verbose == 2) printf("     Message : %s\n", FGD_com);
398         switch (verbose) {
399         case 0: // printf("%d\n",current_port);
400               break;
401         case 1: service_info = getservbyport(htons(current_port),"tcp");
402               if (!service_info) {
403               printf("%d -> service name unknown\n",current_port);
404               } else {
405               printf("%d -> %s\n",current_port,service_info->s_name);
406               }
407               break; 
408         case 2: service_info = getservbyport(htons(current_port),"tcp");
409               if (!service_info) {
410               printf("     Port %d found. Service name unknown\n",current_port);
411               } else {
412               printf("     Port %d found. Service name: %s\n",current_port,service_info->s_name);
413               }
414               break; 
415         } 
416     }  else if (errno == 113) {
417          fprintf(stderr,"No route to host !\n");
418          exit(1);
419        } 
420 /*     fprintf(stderr,"Error %d connecting socket %d to port %d: %s\n",
421                 errno,sock,current_port,sys_errlist[errno]); */ 
422
423 //              service_info = getservbyport(htons(current_port),"tcp");
424 //              if (!service_info) {
425
426
427
428 /* The Receiving Part, fgd returns errormessages, succes, etc... */
429                   do { 
430                      fgd_status = recv( sock, (char *) buffp, 5, MSG_WAITALL);
431                      if (verbose == 2) printf("     status %d\n", fgd_status);
432                      }
433 //                  while ( (fgd_status != 5) && (fgd_status != 0) );
434                   while ( (fgd_status == -1) || (fgd_status == -1) );
435                   fgd_reply_len = (unsigned char) buffp[3] + (unsigned char) buffp[4] * 256;
436                   if (verbose == 2) {
437                       printf("     Got reply : %x %x %x  MSG length %d Bytes\n", 
438                                    buffp[0], buffp[1], buffp[2], fgd_reply_len);
439                   }
440                       if (strncmp( buffp, "FGD", 3) == 0) {
441                       switch ( (char) FGD_com[0] - 0x30) {
442                       case  0: int abc;
443                                abc = read( sock, fgd_name, fgd_reply_len);
444                                if (verbose == 2) printf("readwert: %d", abc);
445                                // fgd_name[buffp[3]] = 0;                      
446                                printf("FGD: FlightGear-Deamon %s detected\n", fgd_name);
447                                break;
448                       case  1: read( sock, fgd_txt, fgd_reply_len);
449                                printf("FGD: Registering Host %s\n", fgd_txt);
450                                break;
451                       case  2: printf("FGD: Showing registered Hosts at %s\n", fgd_host);
452                                if ( fgd_reply_len != 5) {
453 /* FIXME: replace with SELECT to avoid broken pipes, known bug (-; */
454                                   do { 
455                                       fgd_status = recv( sock, fgd_txt, fgd_reply_len - 5, 
456                                                       MSG_WAITALL);
457 //                                    printf("     status %d\n", fgd_status);
458                                   }
459 //                                while ( (fgd_status != 5) && (fgd_status != 0) );
460                                   while ( (fgd_status == -1) || (fgd_status == -1) );                               
461 //                                read( sock, fgd_txt, fgd_reply_len - 5);
462                                   fgd_curpos = 1;
463                                   for (fgd_cnt = 1; fgd_cnt < (fgd_txt[0]+1); fgd_cnt++) {
464                                       fgd_ele_len = fgd_txt[fgd_curpos];
465                                       bcopy( &fgd_txt[fgd_curpos], fgfs_host, fgd_ele_len);
466                                       // fgfs_host[fgd_ele_len] = 0;
467                                       fgd_curpos += fgd_ele_len + 1;
468                                       if (verbose == 2) printf("     #%d  %s\n", fgd_cnt, fgfs_host);
469                                   }
470                                }
471                                break;
472                       case  5: printf("FGD: Receiving data from Host %s\n", FGFS_host);
473                                read( sock, fgd_txt, buffp[3]);
474                                fgd_txt[buffp[3]] = 0;
475                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
476                                    if (verbose == 2) printf("FGD: Data from Host %s received\n", fgd_txt);
477                                    }
478                                    else if (verbose == 2) printf("FGD: Host not in list, sorry...\n");
479                                break;
480                       case 17: if (verbose == 2) printf("FGD: Receiving Mat4 data from Host %s\n", FGFS_host);
481                                read( sock, fgd_txt, fgd_reply_len);
482                                // fgd_txt[buffp[3]] = 0;
483                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
484                                    if (verbose == 2) printf("FGD: Mat4 Data from Host %s received\n", fgd_txt);
485                                    }
486                                    else printf("FGD: Host not in list, sorry...\n");
487                                break;                               
488                       case  6: printf("FGD: Sending data to Host %s\n", FGFS_host);
489                                if (buffp[3] != 4) {
490 /* FIXME: replace with SELECT */
491                   if (verbose == 2) printf("Noch %d bytes\n", (unsigned char) buffp[3]);
492                   do { 
493                     fgd_status = recv( sock, fgd_txt, (unsigned char) buffp[3]-4, MSG_PEEK);
494                     if (verbose == 2) printf("Status %d\n", fgd_status);
495                      }
496                     while ( (fgd_status == 4) || (fgd_status == -1) );
497 //                  while ( (fgd_status == -1) || (fgd_status == -1) );                               
498                                  read( sock, fgd_txt, buffp[3]-4);
499                                  fgd_curpos = 2;
500                                  fgd_ppl_old = fgd_ppl;
501                                  fgd_ppl = fgd_txt[0];
502                                  /* Check if list has changed (pilot joined/left) */
503                                  if (fgd_ppl != fgd_ppl_old) {
504                                    printf(" List changed!!!\n");
505                                    for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
506                                      if (verbose == 2) printf(" Checkpoint\n");
507                                      incoming = head->next;
508                                      if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
509                                      else {
510                                         printf(" Clearing entry.\n");
511                                         list_clear(incoming->ipadr);
512                                      }
513                                    }
514                                  }
515 //                                 else {
516                                    incoming = head->next;
517                                    for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
518                                  /* IP */
519                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
520                                    bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
521                                    incoming->ipadr[fgd_ele_len] = 0;
522                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
523                                  /* Pilot */
524                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
525                                    bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
526                                    incoming->callsign[fgd_ele_len] = 0;
527                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
528                                   /* Lon, Lat...etc */
529                                    if (verbose == 2) {
530                                    printf("     #%d  %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
531                                    printf(" curpos:%d\n", fgd_curpos);
532                                    sscanf( &fgd_txt[fgd_curpos]," %7f %7f %7f %7f %7f %7f %7f",
533                                            &incoming->latf, &incoming->lonf,
534                                            &incoming->altf, &incoming->speedf, &incoming->rollf,
535                                            &incoming->pitchf, &incoming->yawf);
536                                    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",
537                                             incoming->latf, incoming->lonf, incoming->altf, incoming->speedf,
538                                             incoming->rollf, incoming->pitchf, incoming->yawf);                                   
539                                    }         
540                                    fgd_curpos += 56;
541                                    incoming = incoming->next;
542                                    } /* end for                 */
543 //                                 }   /* end else                */
544                                }     /* end if "data available" */
545 /* Here reading the answer of completed command by fgd */
546 /*                               read( sock, fgd_txt, buffp[3]);
547                                fgd_txt[buffp[3]] = 0;
548                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
549                                    if (verbose == 2) printf("FGD: Data to Host sent\n");
550                                    }
551                                    else printf("FGD: Host not in list, sorry...\n");
552 */                                   
553                                break;
554                       case 18: if (verbose == 2) printf("FGD: Sending Mat4 data to Host %s\n", FGFS_host);
555                                if (fgd_reply_len != 5) {
556 /* FIXME: replace with SELECT */
557                                  if (verbose == 2) printf("Noch %d bytes\n", fgd_reply_len);
558                                  do { 
559                                      fgd_status = recv( sock, fgd_txt, fgd_reply_len - 5, MSG_WAITALL);
560                                      if (verbose == 2) printf("Status %d\n", fgd_status);
561                                  }
562 //                                 while ( (fgd_status == 4) || (fgd_status == -1) );
563                                  while ( (fgd_status == -1) || (fgd_status == -1) );
564 //                                 read( sock, fgd_txt, fgd_reply_len - 5);
565                                  fgd_curpos = 2;
566                                  fgd_ppl_old = fgd_ppl;
567                                  fgd_ppl = fgd_txt[0];
568                                  /* Check if list has changed (pilot joined/left) */
569                                  if (fgd_ppl != fgd_ppl_old) {
570                                    printf(" List changed!!!\n");
571                                    for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
572                                      if (verbose == 2) printf(" Checkpoint\n");
573                                      incoming = head->next;
574                                      if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
575                                      else {
576                                         printf(" Clearing entry.\n");
577                                         list_clear(incoming->ipadr);
578                                      }
579                                    }
580                                  }
581 //                                 else {
582                                    incoming = head->next;
583                                    for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
584                                  /* IP */
585                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
586                                    bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
587                                    incoming->ipadr[fgd_ele_len] = 0;
588                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
589                                  /* Pilot */
590                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
591                                    bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
592                                    incoming->callsign[fgd_ele_len] = 0;
593                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
594                                   /* Lon, Lat...etc */
595                                    if (verbose == 2) {
596                                      printf("     #%d  %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
597                                      printf(" curpos:%d\n", fgd_curpos);
598                                    }
599                                    fgd_len_msg = strlen ( &fgd_txt[fgd_curpos]);
600                                    sscanf( &fgd_txt[fgd_curpos]," %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
601                                            &incoming->sgFGD_COORD[0][0], &incoming->sgFGD_COORD[0][1], &incoming->sgFGD_COORD[0][2], &incoming->sgFGD_COORD[0][3],
602                                            &incoming->sgFGD_COORD[1][0], &incoming->sgFGD_COORD[1][1], &incoming->sgFGD_COORD[1][2], &incoming->sgFGD_COORD[1][3],
603                                            &incoming->sgFGD_COORD[2][0], &incoming->sgFGD_COORD[2][1], &incoming->sgFGD_COORD[2][2], &incoming->sgFGD_COORD[2][3],
604                                            &incoming->sgFGD_COORD[3][0], &incoming->sgFGD_COORD[3][1], &incoming->sgFGD_COORD[3][2], &incoming->sgFGD_COORD[3][3]);
605                                    
606                                    if (verbose == 2) {
607                                      printf("Incoming Mat4\n");
608                                      fgd_print_Mat4( incoming->sgFGD_COORD );        
609                                    }
610                                    fgd_curpos += fgd_len_msg + 2;
611                                    incoming = incoming->next;
612                                    } /* end for                 */
613 //                                 }   /* end else                */
614                                }     /* end if "data available" */
615                                /* The first view-Mat4 is somebody else */
616                                sgCopyMat4(sgFGD_VIEW, head->next->sgFGD_COORD);
617
618 /* Here reading the answer of completed command by fgd */
619 /*                               read( sock, fgd_txt, buffp[3]);
620 //                               fgd_txt[buffp[3]] = 0;
621                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
622                                    if (verbose == 2) printf("FGD: Mat4 Data to Host sent\n");
623                                    }
624                                    else printf("FGD: Host not in list, sorry...\n");
625 */                                   
626                                break;
627                       case  8: printf("FGD: Unregistering Host %s\n", FGFS_host);
628                                read( sock, fgd_txt, buffp[3]);
629                                fgd_txt[buffp[3]] = 0;
630                                test = head->next;
631                                while (test != tail) {
632                                   list_clear( test->ipadr );
633                                   test = test->next;
634                                }
635                                fgd_ppl = 0;
636 /*
637                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
638                                    printf("FGD: Host %s unregistered\n", fgd_txt);
639                                    }
640                                    else printf("FGD: Host not in list, sorry...\n"); */
641                                break;                               
642                       case  9: printf(" Shutdown FlightGear-Deamon %s .\n", fgd_name);
643                                break;                               
644                       default: break;
645                       }
646                   } else printf("     Huh?: no deamon present, yuk!!!\n");
647 //              }
648        close(sock);
649 //       current_port++;
650 //   }
651
652   if (verbose == 2) printf("fgd_com completed.\n");
653 }