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