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