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