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