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