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