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