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