]> git.mxchange.org Git - flightgear.git/blob - src/NetworkOLK/net_send.cxx
0d59262488d77ace44013af5c229fcab2ebe32d4
[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 const char *const *sys_errlist = _sys_errlist;
57 #else
58 extern const char *const sys_errlist[];
59 extern int errno;
60 #endif
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",base_port,end_port);
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",base_port,end_port);
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    return 0;
312 }
313
314
315 void fgd_send_com( char *FGD_com, char *FGFS_host) {
316
317    strcpy( buffp, "                ");
318 //   current_port = base_port;
319    if (verbose == 2) printf("     Sending : %s\n", FGD_com);
320 //   while (current_port <= end_port) {
321 /*  fprintf(stderr,"Trying port: %d\n",current_port); */
322     sock = socket(PF_INET, SOCK_STREAM, 0);
323     if (sock == -1)
324      {
325         fprintf(stderr, "Error assigning master socket: %s\n",sys_errlist[errno]);
326         /* must check how severe this really is */
327         // exit(-1);
328      } 
329
330     address.sin_port = htons(current_port);
331     if (verbose == 2) printf("     address.sin_port : %d\n",htons(address.sin_port));
332
333     f_host_info = gethostbyname(src_host);
334
335 //printf ("src_host : %s", ntohs(f_host_info->h_addr));
336     
337     if (connect(sock, (struct sockaddr *)&address, sizeof(address)) == 0) {
338 /* FIXME:    make a single string instead of sending elements */
339
340         fgd_len_msg = (int) sizeof(f_host_info->h_addr);
341 /* send length of sender-ip */
342         write( sock, &fgd_len_msg,1);
343 /* send sender-ip */
344         write( sock, f_host_info->h_addr, fgd_len_msg);
345 /* send commando */     
346         write( sock, FGD_com, 1);
347 /* send length of dummy-string, for the moment with _WHO_ to execute commando 
348    here: his length of ip  */
349         f_host_info = gethostbyname(FGFS_host);
350         fgd_len_msg = (int) sizeof(f_host_info->h_addr);
351         write( sock, &fgd_len_msg,1);
352 /* send dummy-string, for the moment with _WHO_ to execute commando 
353    here: his ip  */   
354         write( sock, f_host_info->h_addr, fgd_len_msg);
355 /* END FIXME  */
356
357 /* Here we send subsequent data... */
358         switch  ( (char) FGD_com[0] - 0x30) {
359         case 5:  fgd_len_msg = strlen( net_callsign);
360                  write( sock, &fgd_len_msg,1);
361         /* send string, for the moment, here: callsign */   
362                  write( sock, net_callsign, fgd_len_msg);
363         /* Lon, Lat, Alt, Speed, Roll, Pitch, Yaw
364            hope this sprintf call is not too expensive */
365                  sprintf( fgd_txt, " %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f", 
366 //                          boss->latf, boss->lonf, boss->altf, boss->speedf,
367 //                          boss->rollf, boss->pitchf, boss->yawf);
368 /* 
369    Must decide if it's better to send values "as are" or convert them for
370    deamon, better is to let deamon make the job. Anyway this will depend on 
371    speed loss/gain in network-area...
372 */
373                           get_latitude(), get_longitude(), get_altitude(),
374                           get_speed(), get_roll()*RAD_TO_DEG,
375                           get_pitch()*RAD_TO_DEG, get_heading());
376                  write( sock, fgd_txt, 56);
377                  break;
378
379 /* Here sending the previously calculated view.Mat4 by FGFS */
380         case 17: if (verbose == 2) printf("Checkpoint\n");
381                  sgCopyMat4(sgFGD_COORD, current_view.VIEW);
382
383                  if (verbose == 2) {
384                     printf("current_view\n");
385                     fgd_print_Mat4( current_view.VIEW);
386                     printf("FGD_COORD\n");
387                     fgd_print_Mat4( sgFGD_COORD);
388                  }
389                  fgd_len_msg = strlen( net_callsign);
390                  write( sock, &fgd_len_msg,1);
391         /* send string, for the moment, here: callsign */   
392                  write( sock, net_callsign, fgd_len_msg);
393         /* MATRIX-variant of Lon, Lat etc...
394            hope this sprintf call is not too expensive */
395                  fgd_len_msg = sprintf( fgd_txt, " %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
396                           sgFGD_COORD[0][0], sgFGD_COORD[0][1], sgFGD_COORD[0][2], sgFGD_COORD[0][3],
397                           sgFGD_COORD[1][0], sgFGD_COORD[1][1], sgFGD_COORD[1][2], sgFGD_COORD[1][3],
398                           sgFGD_COORD[2][0], sgFGD_COORD[2][1], sgFGD_COORD[2][2], sgFGD_COORD[2][3],
399                           sgFGD_COORD[3][0], sgFGD_COORD[3][1], sgFGD_COORD[3][2], sgFGD_COORD[3][3]);
400                  fgd_txt[fgd_len_msg] = 0;
401                  write( sock, fgd_txt, fgd_len_msg+1);
402                  break;
403         default: break;
404         }
405         
406
407 /* be verbose, this goes later into own (*void) */ 
408         if (verbose == 2) printf("     Message : %s\n", FGD_com);
409         switch (verbose) {
410         case 0: // printf("%d\n",current_port);
411               break;
412         case 1: service_info = getservbyport(htons(current_port),"tcp");
413               if (!service_info) {
414               printf("%d -> service name unknown\n",current_port);
415               } else {
416               printf("%d -> %s\n",current_port,service_info->s_name);
417               }
418               break; 
419         case 2: service_info = getservbyport(htons(current_port),"tcp");
420               if (!service_info) {
421               printf("     Port %d found. Service name unknown\n",current_port);
422               } else {
423               printf("     Port %d found. Service name: %s\n",current_port,service_info->s_name);
424               }
425               break; 
426         } 
427     }  else if (errno == 113) {
428          fprintf(stderr,"No route to host !\n");
429          /* must check this */
430          // exit(1);
431        } 
432 /*     fprintf(stderr,"Error %d connecting socket %d to port %d: %s\n",
433                 errno,sock,current_port,sys_errlist[errno]); */ 
434
435 //              service_info = getservbyport(htons(current_port),"tcp");
436 //              if (!service_info) {
437
438
439
440 /* The Receiving Part, fgd returns errormessages, succes, etc... */
441                   do { 
442                      fgd_status = recv( sock, (char *) buffp, 5, MSG_WAITALL);
443                      if (verbose == 2) printf("     status %d\n", fgd_status);
444                      }
445 //                  while ( (fgd_status != 5) && (fgd_status != 0) );
446                   while ( (fgd_status == -1) || (fgd_status == -1) );
447                   fgd_reply_len = (unsigned char) buffp[3] + (unsigned char) buffp[4] * 256;
448                   if (verbose == 2) {
449                       printf("     Got reply : %x %x %x  MSG length %d Bytes\n", 
450                                    buffp[0], buffp[1], buffp[2], fgd_reply_len);
451                   }
452                       if (strncmp( buffp, "FGD", 3) == 0) {
453                       switch ( (char) FGD_com[0] - 0x30) {
454                       case  0: int abc;
455                                abc = read( sock, fgd_name, fgd_reply_len);
456                                if (verbose == 2) printf("readwert: %d", abc);
457                                // fgd_name[buffp[3]] = 0;                      
458                                printf("FGD: FlightGear-Deamon %s detected\n", fgd_name);
459                                break;
460                       case  1: read( sock, fgd_txt, fgd_reply_len);
461                                printf("FGD: Registering Host %s\n", fgd_txt);
462                                break;
463                       case  2: printf("FGD: Showing registered Hosts at %s\n", fgd_host);
464                                if ( fgd_reply_len != 5) {
465 /* FIXME: replace with SELECT to avoid broken pipes, known bug (-; */
466                                   do { 
467                                       fgd_status = recv( sock, fgd_txt, fgd_reply_len - 5, 
468                                                       MSG_WAITALL);
469 //                                    printf("     status %d\n", fgd_status);
470                                   }
471 //                                while ( (fgd_status != 5) && (fgd_status != 0) );
472                                   while ( (fgd_status == -1) || (fgd_status == -1) );                               
473 //                                read( sock, fgd_txt, fgd_reply_len - 5);
474                                   fgd_curpos = 1;
475                                   for (fgd_cnt = 1; fgd_cnt < (fgd_txt[0]+1); fgd_cnt++) {
476                                       fgd_ele_len = fgd_txt[fgd_curpos];
477                                       bcopy( &fgd_txt[fgd_curpos], fgfs_host, fgd_ele_len);
478                                       // fgfs_host[fgd_ele_len] = 0;
479                                       fgd_curpos += fgd_ele_len + 1;
480                                       if (verbose == 2) printf("     #%d  %s\n", fgd_cnt, fgfs_host);
481                                   }
482                                }
483                                break;
484                       case  5: printf("FGD: Receiving data from Host %s\n", FGFS_host);
485                                read( sock, fgd_txt, buffp[3]);
486                                fgd_txt[buffp[3]] = 0;
487 /* This works...
488                                if (strcmp(fgd_txt, "UNKNOWN") == 0) {
489                                    printf("FGD: Host not in list, sorry...\n");
490                                }
491                                else printf("FGD: Data from Host %s received\n", fgd_txt);
492 */
493 /* This has problem with glibc-2.1
494                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
495                                    if (verbose == 2) printf("FGD: Data from Host %s received\n", fgd_txt);
496                                    }
497                                    else if (verbose == 2) printf("FGD: Host not in list, sorry...\n");
498 */
499                                break;
500                       case 17: if (verbose == 2) printf("FGD: Receiving Mat4 data from Host %s\n", FGFS_host);
501                                read( sock, fgd_txt, fgd_reply_len);
502                                // fgd_txt[buffp[3]] = 0;
503                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
504                                    if (verbose == 2) printf("FGD: Mat4 Data from Host %s received\n", fgd_txt);
505                                    }
506                                    else printf("FGD: Host not in list, sorry...\n");
507                                break;                               
508                       case  6: printf("FGD: Sending data to Host %s\n", FGFS_host);
509                                if (buffp[3] != 4) {
510 /* FIXME: replace with SELECT */
511                   if (verbose == 2) printf("Noch %d bytes\n", (unsigned char) buffp[3]);
512                   do { 
513                     fgd_status = recv( sock, fgd_txt, (unsigned char) buffp[3]-4, MSG_PEEK);
514                     if (verbose == 2) printf("Status %d\n", fgd_status);
515                      }
516                     while ( (fgd_status == 4) || (fgd_status == -1) );
517 //                  while ( (fgd_status == -1) || (fgd_status == -1) );                               
518                                  read( sock, fgd_txt, buffp[3]-4);
519                                  fgd_curpos = 2;
520                                  fgd_ppl_old = fgd_ppl;
521                                  fgd_ppl = fgd_txt[0];
522                                  /* Check if list has changed (pilot joined/left) */
523                                  if (fgd_ppl != fgd_ppl_old) {
524                                    printf(" List changed!!!\n");
525                                    for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
526                                      if (verbose == 2) printf(" Checkpoint\n");
527                                      incoming = head->next;
528                                      if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
529                                      else {
530                                         printf(" Clearing entry.\n");
531                                         list_clear(incoming->ipadr);
532                                      }
533                                    }
534                                  }
535 //                                 else {
536                                    incoming = head->next;
537                                    for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
538                                  /* IP */
539                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
540                                    bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
541                                    incoming->ipadr[fgd_ele_len] = 0;
542                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
543                                  /* Pilot */
544                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
545                                    bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
546                                    incoming->callsign[fgd_ele_len] = 0;
547                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
548                                   /* Lon, Lat...etc */
549                                    if (verbose == 2) {
550                                    printf("     #%d  %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
551                                    printf(" curpos:%d\n", fgd_curpos);
552                                    sscanf( &fgd_txt[fgd_curpos]," %7f %7f %7f %7f %7f %7f %7f",
553                                            &incoming->latf, &incoming->lonf,
554                                            &incoming->altf, &incoming->speedf, &incoming->rollf,
555                                            &incoming->pitchf, &incoming->yawf);
556                                    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",
557                                             incoming->latf, incoming->lonf, incoming->altf, incoming->speedf,
558                                             incoming->rollf, incoming->pitchf, incoming->yawf);                                   
559                                    }         
560                                    fgd_curpos += 56;
561                                    incoming = incoming->next;
562                                    } /* end for                 */
563 //                                 }   /* end else                */
564                                }     /* end if "data available" */
565 /* Here reading the answer of completed command by fgd */
566 /*                               read( sock, fgd_txt, buffp[3]);
567                                fgd_txt[buffp[3]] = 0;
568                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
569                                    if (verbose == 2) printf("FGD: Data to Host sent\n");
570                                    }
571                                    else printf("FGD: Host not in list, sorry...\n");
572 */                                   
573                                break;
574                       case 18: if (verbose == 2) printf("FGD: Sending Mat4 data to Host %s\n", FGFS_host);
575                                if (fgd_reply_len != 5) {
576 /* FIXME: replace with SELECT */
577                                  if (verbose == 2) printf("Noch %d bytes\n", fgd_reply_len);
578                                  do { 
579                                      fgd_status = recv( sock, fgd_txt, fgd_reply_len - 5, MSG_WAITALL);
580                                      if (verbose == 2) printf("Status %d\n", fgd_status);
581                                  }
582 //                                 while ( (fgd_status == 4) || (fgd_status == -1) );
583                                  while ( (fgd_status == -1) || (fgd_status == -1) );
584 //                                 read( sock, fgd_txt, fgd_reply_len - 5);
585                                  fgd_curpos = 2;
586                                  fgd_ppl_old = fgd_ppl;
587                                  fgd_ppl = fgd_txt[0];
588                                  /* Check if list has changed (pilot joined/left) */
589                                  if (fgd_ppl != fgd_ppl_old) {
590                                    printf(" List changed!!!\n");
591                                    for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
592                                      if (verbose == 2) printf(" Checkpoint\n");
593                                      incoming = head->next;
594                                      if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
595                                      else {
596                                         printf(" Clearing entry.\n");
597                                         list_clear(incoming->ipadr);
598                                      }
599                                    }
600                                  }
601 //                                 else {
602                                    incoming = head->next;
603                                    for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
604                                  /* IP */
605                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
606                                    bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
607                                    incoming->ipadr[fgd_ele_len] = 0;
608                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
609                                  /* Pilot */
610                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
611                                    bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
612                                    incoming->callsign[fgd_ele_len] = 0;
613                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
614                                   /* Lon, Lat...etc */
615                                    if (verbose == 2) {
616                                      printf("     #%d  %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
617                                      printf(" curpos:%d\n", fgd_curpos);
618                                    }
619                                    fgd_len_msg = strlen ( &fgd_txt[fgd_curpos]);
620                                    sscanf( &fgd_txt[fgd_curpos]," %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
621                                            &incoming->sgFGD_COORD[0][0], &incoming->sgFGD_COORD[0][1], &incoming->sgFGD_COORD[0][2], &incoming->sgFGD_COORD[0][3],
622                                            &incoming->sgFGD_COORD[1][0], &incoming->sgFGD_COORD[1][1], &incoming->sgFGD_COORD[1][2], &incoming->sgFGD_COORD[1][3],
623                                            &incoming->sgFGD_COORD[2][0], &incoming->sgFGD_COORD[2][1], &incoming->sgFGD_COORD[2][2], &incoming->sgFGD_COORD[2][3],
624                                            &incoming->sgFGD_COORD[3][0], &incoming->sgFGD_COORD[3][1], &incoming->sgFGD_COORD[3][2], &incoming->sgFGD_COORD[3][3]);
625                                    
626                                    if (verbose == 2) {
627                                      printf("Incoming Mat4\n");
628                                      fgd_print_Mat4( incoming->sgFGD_COORD );        
629                                    }
630                                    fgd_curpos += fgd_len_msg + 2;
631                                    incoming = incoming->next;
632                                    } /* end for                 */
633 //                                 }   /* end else                */
634                                }     /* end if "data available" */
635                                /* The first view-Mat4 is somebody else */
636                                sgCopyMat4(sgFGD_VIEW, head->next->sgFGD_COORD);
637
638 /* Here reading the answer of completed command by fgd */
639 /*                               read( sock, fgd_txt, buffp[3]);
640 //                               fgd_txt[buffp[3]] = 0;
641                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
642                                    if (verbose == 2) printf("FGD: Mat4 Data to Host sent\n");
643                                    }
644                                    else printf("FGD: Host not in list, sorry...\n");
645 */                                   
646                                break;
647                       case  8: printf("FGD: Unregistering Host %s\n", FGFS_host);
648                                read( sock, fgd_txt, buffp[3]);
649                                fgd_txt[buffp[3]] = 0;
650                                test = head->next;
651                                while (test != tail) {
652                                   list_clear( test->ipadr );
653                                   test = test->next;
654                                }
655                                fgd_ppl = 0;
656 /*  This does...
657                                if (strcmp(fgd_txt, "UNKNOWN") == 0) {
658                                    printf("FGD: Host not in list, sorry...\n");
659                                }
660                                else printf("FGD: Host %s unregistered\n", fgd_txt);
661 */
662 /*  This does not work on glibc-2.1
663                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
664                                    printf("FGD: Host %s unregistered\n", fgd_txt);
665                                    }
666                                else printf("FGD: Host not in list, sorry...\n"); 
667 */
668                                break;                               
669                       case  9: printf(" Shutdown FlightGear-Deamon %s .\n", fgd_name);
670                                break;                               
671                       default: break;
672                       }
673                   } else printf("     Huh?: no deamon present, yuk!!!\n");
674 //              }
675        close(sock);
676 //       current_port++;
677 //   }
678
679   if (verbose == 2) printf("fgd_com completed.\n");
680 }