]> git.mxchange.org Git - flightgear.git/blob - src/NetworkOLK/Tools/fgd_mcp.c
Code reorganization.
[flightgear.git] / src / NetworkOLK / Tools / fgd_mcp.c
1 /*************************************************************/
2 /* FGD_MCP.C 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/glibc-2.0    */
31 /*                                        glibc-2.1 cleanups */
32 /*************************************************************/
33
34 #include <stdio.h>
35 #include "fgd.h"
36 #include <math.h>
37
38 //#define printf //
39
40 /* Netstuff */
41 int sock = -1;
42 int my_sock;
43 struct sockaddr_in address;
44 struct sockaddr_in my_address;
45 int result;
46 extern int errno;
47 int current_port  = 10000; 
48 u_short base_port = 10000;
49 u_short end_port  = 10000;
50 int verbose = 2;
51 struct hostent *host_info, *f_host_info;
52 struct servent *service_info;
53 struct utsname myname;
54
55 /* Program-stuff */
56 int i, j;
57 int fgd_len_msg = 1, fgd_status, fgd_ele_len, fgd_curpos, fgd_cnt, fgd_ppl,
58     fgd_ppl_old, fgd_loss;
59 size_t anz;
60 char *fgd_job, *fgd_callsign, *fgd_name, *fgd_ip, *fgd_mcp_ip;
61 char *buffp, *src_host, *fgd_host, *fgfs_host, *fgfs_pilot, *fgd_txt;
62
63 /* List-stuff */
64
65 const int True  = 0;
66 const int False= -1;
67
68 struct list_ele {
69    unsigned char ipadr[16], callsign[16];
70    unsigned char lon[8], lat[8], alt[8], roll[8], pitch[8], yaw[8];
71    float lonf, latf, altf, speedf, rollf, pitchf, yawf;   
72    struct list_ele *next, *prev;
73 };
74
75 struct list_ele *head, *tail, *act, *test, *incoming, *boss, *other;  /* fgd_msg; */
76
77 /*...Create head and tail of list */
78 void list_init( void) {
79
80    incoming = (struct list_ele*) malloc(sizeof(struct list_ele));
81    boss = (struct list_ele*) malloc(sizeof(struct list_ele));
82    other = (struct list_ele*) malloc(sizeof(struct list_ele));
83    head = (struct list_ele*) malloc(sizeof(struct list_ele));
84    tail = (struct list_ele*) malloc(sizeof(struct list_ele));
85    if (head == NULL || tail == NULL) { printf("Out of memory\n"); exit(1); }
86    head->ipadr[0] = 0;
87    tail->ipadr[0] = 255;
88    tail->ipadr[1] = 0;
89    head->prev = tail->prev = head;
90    head->next = tail->next = tail;
91    act = head;          /* put listpointer to beginning of list */
92 }
93
94 void list_output( void) {
95 }
96
97 void list_search( char name[16]) {
98
99    if (strcmp(name, head->next->ipadr) <= 0)     act = head;
100    else if (strcmp(name, tail->prev->ipadr) > 0) act = tail->prev;
101    else {
102       int vergleich = strcmp(name, act->ipadr);
103       if (vergleich > 0)
104          while (strcmp(name, act->next->ipadr) > 0) {
105             act = act->next;
106          }
107       else if (vergleich < 0)
108          while (strcmp(name, act->ipadr) < 0) {
109             act = act->prev;
110          }
111       else
112          while (strcmp(name, act->ipadr) == 0) {
113             act = act->prev;
114          }
115    }
116 }
117
118 void list_insert( char newip[16]) {
119 struct list_ele *new_ele;
120
121    new_ele = (struct list_ele*) malloc(sizeof(struct list_ele));
122    if (new_ele == NULL) { printf("Out of memory\n"); exit(1); }
123    strcpy(new_ele->ipadr, newip);
124 /* setting default */
125    strcpy(new_ele->callsign, "not assigned");
126    list_search( newip);
127    new_ele->prev = act;
128    new_ele->next = act->next;
129    act->next->prev = act->next = new_ele;
130 }
131
132 void list_setval( char newip[16]) {
133
134    list_search( newip);
135    strcpy( act->next->callsign, incoming->callsign);
136    printf("Callsign %s\n", act->next->callsign);
137    
138 }
139
140 void list_clear( char clrip[16]) {
141 struct list_ele *clr_ele;
142
143    list_search( clrip);
144    if ( strcmp( clrip, act->next->ipadr))
145       printf("....Name %s nicht vorhanden", clrip);
146    else {
147      clr_ele         = act->next;
148      act->next       = act->next->next;
149      act->next->prev = act;
150      free( clr_ele);
151    }
152 }
153
154 int list_not_in( char name[16]) {
155    
156    i = True;
157    test = head->next;
158    while ((test != tail) && (i==True)) {
159      i = (strcmp(test->ipadr, name) ? True : False);
160      test = test->next;
161      if (verbose != 0) printf("list_not_in : %d\n",i);
162    }
163    return(i);
164 }
165
166 void fgd_init(void){
167
168 /* Let's init a few things */
169    printf("MCP: Allocating memory...");
170    buffp = (char *) malloc(1024); /* No I don't check if there are another KB */
171    fgd_job = (char *) malloc(8);     
172    fgd_host = (char *) malloc(64);
173    fgd_callsign = (char *) malloc(64);
174    fgd_name = (char*) malloc(64);
175    fgd_ip = (char *) malloc(16);
176    fgd_mcp_ip = (char *) malloc(16);
177    fgfs_host = (char *) malloc(64);
178    fgfs_pilot = (char *) malloc(64);
179    src_host = (char *) malloc(64);
180    fgd_txt = (char *) malloc(1024);
181    printf("ok\nMCP: Initializing values...");   
182    strcpy( fgd_job, "xxx");
183    strcpy( fgd_host, "Johnny");
184    strcpy( fgd_callsign, "Unknown");
185    strcpy( fgd_name, "Unknown");
186    strcpy( fgd_ip, (char *) inet_ntoa(address.sin_addr));
187    strcpy( fgd_txt, "");
188    printf("ok\n");
189    boss->latf = 112.3;
190    boss->lonf = 4.5;
191    boss->altf = 0.67;
192    boss->speedf = 100.95;
193    boss->rollf = 89.0;
194    boss->pitchf = 1.23;
195    boss->yawf = 456.789;
196    fgd_ppl = 0;
197    bzero((char *)&address, sizeof(address));
198    address.sin_family = AF_INET;
199 /* determinating the source/sending host */
200    if (uname(&myname) == 0) strcpy(src_host , myname.nodename);   
201    printf("MCP: I'm running on HOST : %s   ", src_host);
202    if (host_info = gethostbyname( src_host)) {
203      bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
204      strcpy((char *) fgd_mcp_ip, (char *) inet_ntoa(address.sin_addr));
205      }
206    printf("IP : %s\n", fgd_mcp_ip);   
207 /* resolving the destination host, here fgd's host */   
208    if (verbose == 2) printf("     Resolving default DEAMON: %s ->", fgd_host);
209    if (host_info = gethostbyname( fgd_host)) {
210      bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
211      strcpy((char *) fgd_ip, (char *) inet_ntoa(address.sin_addr));
212      if (verbose == 2) {
213         printf(" resolved\n     FGD running on HOST : %s", fgd_host);
214         printf("   IP : %s\n", fgd_ip);
215      }
216    } else if ((address.sin_addr.s_addr = inet_addr( fgd_host)) == INADDR_NONE) {
217             printf(" NOT resolved !!!\n");
218             printf("MCP: Could not get %s host entry !\n", fgd_host);
219             printf("MCP: Enter '10' for deamon IP or fqdn or alias. (your choice)\n");
220 //          exit(1);
221           } else if (verbose == 2) printf(" address valid\n");
222    
223    if ((base_port > end_port) || ((short)base_port < 0)) { 
224             printf("MCP: Bad port range : start=%d end=%d !\n");
225             printf("MCP: Enter '10' for deamon IP/fqdn\n");     
226      exit(1);
227    } else if (verbose == 2) {
228             printf("     Port range: %d to %d\n",base_port,end_port);
229             }
230 }
231
232
233 void fgd_send_com( char *FGD_com, char *FGFS_host) {
234
235    strcpy( buffp, "                ");
236    current_port = base_port;
237    printf("     Sending : %s\n", FGD_com);
238    while (current_port <= end_port) {
239 /*  fprintf(stderr,"Trying port: %d\n",current_port); */
240     sock = socket(PF_INET, SOCK_STREAM, 0);
241     if (sock == -1)
242      {
243         fprintf(stderr, "Error assigning master socket: %s\n",sys_errlist[errno]);
244         exit(-1);
245      } 
246
247     address.sin_port = htons(current_port);
248     printf("     address.sin_port : %d\n",htons(address.sin_port));
249
250     f_host_info = gethostbyname(src_host);
251
252 //printf ("src_host : %s", ntohs(f_host_info->h_addr));
253     
254     if (connect(sock, (struct sockaddr *)&address, sizeof(address)) == 0) {
255 /* FIXME:    make a single string instead of sending elements */
256
257         fgd_len_msg = (int) sizeof(f_host_info->h_addr);
258 /* send length of sender-ip */
259         write( sock, &fgd_len_msg,1);
260 /* send sender-ip */
261         write( sock, f_host_info->h_addr, fgd_len_msg);
262 /* send commando */     
263         write( sock, FGD_com, 1);
264 /* send length of dummy-string, for the moment with _WHO_ to execute commando 
265    here: his length of ip  */
266         f_host_info = gethostbyname(FGFS_host);
267         fgd_len_msg = (int) sizeof(f_host_info->h_addr);
268         write( sock, &fgd_len_msg,1);
269 /* send dummy-string, for the moment with _WHO_ to execute commando 
270    here: his ip  */   
271         write( sock, f_host_info->h_addr, fgd_len_msg);
272 /* END FIXME  */
273
274 /* Here we send subsequent data... */
275         switch  (atoi((char *) FGD_com)) {
276         case 5:  fgd_len_msg = strlen( fgd_callsign);
277                  write( sock, &fgd_len_msg,1);
278         /* send string, for the moment, here: callsign */   
279                  write( sock, fgd_callsign, fgd_len_msg);
280         /* Lon, Lat, Alt, Speed, Roll, Pitch, Yaw
281            hope this sprintf call is not too expensive */
282                  sprintf( fgd_txt, " %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f %7.3f", 
283                           boss->latf, boss->lonf, boss->altf, boss->speedf,
284                           boss->rollf, boss->pitchf, boss->yawf);
285                  write( sock, fgd_txt, 56);
286                  break;
287         default: break;
288         }
289         
290
291 /* be verbose, this goes later into own (*void) */ 
292         printf("     Message : %s\n", FGD_com);
293         switch (verbose) {
294         case 0: printf("%d\n",current_port);
295               break;
296         case 1: service_info = getservbyport(htons(current_port),"tcp");
297               if (!service_info) {
298               printf("%d -> service name unknown\n",current_port);
299               } else {
300               printf("%d -> %s\n",current_port,service_info->s_name);
301               }
302               break; 
303         case 2: service_info = getservbyport(htons(current_port),"tcp");
304               if (!service_info) {
305               printf("     Port %d found. Service name unknown\n",current_port);
306               } else {
307               printf("     Port %d found. Service name: %s\n",current_port,service_info->s_name);
308               }
309               break; 
310         } 
311     }  else if (errno == 113) {
312          fprintf(stderr,"No route to host !\n");
313          exit(1);
314        } 
315 /*     fprintf(stderr,"Error %d connecting socket %d to port %d: %s\n",
316                 errno,sock,current_port,sys_errlist[errno]); */ 
317
318 //              service_info = getservbyport(htons(current_port),"tcp");
319 //              if (!service_info) {
320
321
322
323 /* The Receiving Part, fgd returns errormessages, succes, etc... */
324                   do { 
325                      fgd_status = recv( sock, (char *) buffp, 5, MSG_WAITALL);
326                      printf("     status %d\n", fgd_status);
327                      }
328 //                  while ( (fgd_status != 5) && (fgd_status != 0) );
329                   while ( (fgd_status == -1) || (fgd_status == -1) );
330                   if (verbose == 2) {
331                       printf("     Got reply : %x %x %x\n", buffp[0], buffp[1], buffp[2]);
332                       printf("     Got reply : %x\n", &buffp);
333                   }
334                   if (strncmp( buffp, "FGD", 3) == 0) {
335                       switch (atoi((char *) FGD_com)) {
336                       case  0: read( sock, fgd_name, buffp[3]);
337                                fgd_name[buffp[3]] = 0;                      
338                                printf("FGD: FlightGear-Deamon %s detected\n", fgd_name);
339                                break;
340                       case  1: printf("FGD: Registering Host %s\n", FGFS_host);
341                                break;
342                       case  2: printf("FGD: Showing registered Hosts at %s\n", fgd_host);
343                                printf(" %d %d\n", buffp[3], buffp[4]);
344                                if ( (buffp[3] + 256 * buffp[4]) != 5 ) {
345 /* FIXME: replace with SELECT to avoid broken pipes, known bug (-;       */
346 /*        but the transfer is calculated very accurately, null problemo  */
347                   do { 
348                       fgd_status = recv( sock, fgd_txt, buffp[3]-5, MSG_WAITALL);
349 //                    printf("     status %d\n", fgd_status);
350                      }
351 //                  while ( (fgd_status != 4) && (fgd_status != 0) );
352                   while ( (fgd_status == -1) || (fgd_status == -1) );                               
353 //                                 read( sock, fgd_txt, buffp[3]-5);
354                                  fgd_curpos = 2;
355                                  for (fgd_cnt = 1; fgd_cnt < (fgd_txt[0]+1); fgd_cnt++) {
356                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
357                                    bcopy( &fgd_txt[fgd_curpos], fgfs_host, fgd_ele_len);
358                                    fgfs_host[fgd_ele_len] = 0;
359                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
360                                    printf("     #%d  %s\n", fgd_cnt, fgfs_host);
361                                  }
362                                }
363                                break;
364                       case  5: printf("FGD: Receiving data from Host %s\n", FGFS_host);
365                                read( sock, fgd_txt, (unsigned char) buffp[3] + 256 * (unsigned char) buffp[4]);
366                                fgd_txt[buffp[3]] = 0;
367                                if (strcmp(fgd_txt, "UNKNOWN") == 0) {
368                                    printf("FGD: Host not in list, sorry...\n");                               
369                                }
370                                else printf("FGD: Data from Host %s received\n", fgd_txt);
371                                break;
372                       case  6: printf("FGD: Sending data to Host %s\n", FGFS_host);
373                                if (buffp[3] != 5) {
374 /* FIXME: replace with SELECT */
375                   if (verbose == 2) printf("Noch %d bytes\n", (unsigned char) buffp[3] + 256 * (unsigned char) buffp[4]);
376                   do { 
377                     fgd_status = recv( sock, fgd_txt, (unsigned char) buffp[3]-5, MSG_PEEK);
378                     if (verbose == 2) printf("Status %d\n", fgd_status);
379                      }
380                     while ( (fgd_status == 5) || (fgd_status == -1) );
381 //                  while ( (fgd_status == -1) || (fgd_status == -1) );                               
382                                  read( sock, fgd_txt, buffp[3]-5);
383                                  fgd_curpos = 2;
384                                  fgd_ppl_old = fgd_ppl;
385                                  fgd_ppl = fgd_txt[0];
386                                  /* Check if list has changed (pilot joined/left) */
387                                  if (fgd_ppl != fgd_ppl_old) {
388                                    printf(" List changed!!!\n");
389                                    for (fgd_cnt = 1; fgd_cnt <= abs(fgd_ppl - fgd_ppl_old); fgd_cnt++) {
390                                      printf(" Checkpoint\n");
391                                      incoming = head->next;
392                                      if ((fgd_ppl - fgd_ppl_old) > 0) list_insert("test\0");
393                                      else {
394                                         printf(" Clearing entry.\n");
395                                         list_clear(incoming->ipadr);
396                                      }
397                                    }
398                                  }
399 //                                 else {
400                                    incoming = head->next;
401                                    for (fgd_cnt = 1; fgd_cnt < (fgd_ppl+1); fgd_cnt++) {
402                                  /* IP */
403                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
404                                    bcopy( &fgd_txt[fgd_curpos], incoming->ipadr, fgd_ele_len);
405                                    incoming->ipadr[fgd_ele_len] = 0;
406                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
407                                  /* Pilot */
408                                    fgd_ele_len = fgd_txt[fgd_curpos-1];
409                                    bcopy( &fgd_txt[fgd_curpos], incoming->callsign, fgd_ele_len);
410                                    incoming->callsign[fgd_ele_len] = 0;
411                                    fgd_curpos = fgd_curpos + fgd_ele_len + 1;
412                                   /* Lon, Lat...etc */
413                                    printf("     #%d  %-16s %s\n", fgd_cnt, incoming->ipadr, incoming->callsign);
414                                    printf(" curpos:%d\n", fgd_curpos);
415                                    sscanf( &fgd_txt[fgd_curpos]," %7f %7f %7f %7f %7f %7f %7f",
416                                            &incoming->latf, &incoming->lonf,
417                                            &incoming->altf, &incoming->speedf, &incoming->rollf,
418                                            &incoming->pitchf, &incoming->yawf);
419                                    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",
420                                             incoming->latf, incoming->lonf, incoming->altf, incoming->speedf,
421                                             incoming->rollf, incoming->pitchf, incoming->yawf);                                   
422                                    fgd_curpos += 56;
423                                    incoming = incoming->next;
424                                    } /* end for                 */
425 //                                 }   /* end else                */
426                                }     /* end if "data available" */
427 /* Here reading the answer of completed command by fgd */
428 /*                               read( sock, fgd_txt, buffp[3]);
429                                fgd_txt[buffp[3]] = 0;
430                                if (strcmp(fgd_txt, "UNKNOWN") == -1) {
431                                    printf("FGD: Data to Host sent\n");
432                                    }
433                                    else printf("FGD: Host not in list, sorry...\n");
434 */                                   
435                                break;
436                       case  8: printf("FGD: Unregistering Host %s\n", FGFS_host);
437                                read( sock, fgd_txt, buffp[3]);
438                                fgd_txt[buffp[3]] = 0;
439                                if (strcmp(fgd_txt, "UNKNOWN") == 0) {
440                                    printf("FGD: Host not in list, sorry...\n");
441                                    }
442                                    else printf("FGD: Host %s unregistered\n", fgd_txt);
443                                break;                               
444                       case  9: printf(" Shutdown FlightGear-Deamon %s .\n", fgd_name);
445                                break;                               
446                       default: break;
447                       }
448                   } else printf("     Huh?: no deamon present, yuk!!!\n");
449 //              }
450        close(sock);
451        current_port++;
452    }
453
454   if (verbose == 2) printf("fgd_com completed.\n");
455 }
456
457
458 int main(int argc, char **argv) { 
459
460    list_init();
461    fgd_init();
462    for ( ; (atoi( (char*) fgd_job)) != 99;){
463    printf("MCP: ready...enter commando (42 help) ");
464    fgets((char *) fgd_job, 5, stdin);
465 //   if (verbose == 2) printf("MCP: got %s %d\n", (char *) fgd_job, strlen((char *) fgd_job));
466    if ( strcmp( fgd_job, "\n") > 0 ) switch( atoi((char*) fgd_job)) {
467      case  0 : if ( strncmp( (char *) fgd_job, "0", 1) == 0 ){
468                   printf("MCP: Scan for fgd\n");
469                   fgd_send_com( "0", src_host);
470                }
471                break;
472      case  1 : printf("MCP: Register to fgd\n");
473                fgd_send_com( "1", src_host);
474                break;     
475      case  2 : printf("MCP: Show registered\n");
476                fgd_send_com( "2", src_host);
477                break;     
478      case  3 : printf("MCP: Send MSG\n");
479                break;
480      case  4 : printf("MCP: Send MSG to ALL\n");
481                break;     
482      case  5 : printf("MCP: Push Data to fgd\n");
483                fgd_send_com( "5", src_host);
484                break;     
485      case  6 : printf("MCP: Pop Data from fgd\n");
486                fgd_send_com( "6", src_host);
487                break;     
488      case  8 : printf("MCP: Unregister from fgd\n");
489                fgd_send_com( "8", src_host);
490                break;     
491      case  9 : printf("MCP: Shutdown fgd-deamon\n");
492                fgd_send_com( "9", src_host);
493                break;
494      case 10 : printf("MCP: Choose default deamon HOST:\n");
495                printf("     Deamon          Host            IP              Port\n");
496                printf("     %-16s%-16s%-16s%-16d\n", fgd_name, fgd_host, fgd_ip, base_port);
497                printf("\n     Enter new Host:[%s]  ", fgd_host);
498                fgets((char *) fgd_txt, 32, stdin);
499                if ( strlen(fgd_txt) != 1 ) {
500                    strcpy(fgd_host, fgd_txt);
501                    fgd_host[ strlen( fgd_txt) - 1] = 0;
502                    if (host_info = gethostbyname( fgd_host)) {
503                        bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
504                        strcpy((char *) fgd_ip, (char *) inet_ntoa(address.sin_addr));
505                        if (verbose == 2) {
506                            printf("MCP: Resolved...FGD running on HOST : %s", fgd_host);
507                            printf("   IP : %s\n", fgd_ip);
508                        }
509                    } else if ((address.sin_addr.s_addr = inet_addr( fgd_host)) == INADDR_NONE) {
510                               fprintf(stderr,"MCP: Could not get %s host entry !\n", fgd_host);
511                               printf("     NOT resolved !!!\n");
512 //                            exit(1);
513                           } else if (verbose == 2) printf(" address valid\n");
514                }
515                break;
516      case 11 : printf("MCP: Choose default deamon Port:\n");
517                printf("     Deamon          Host            IP              Port\n");
518                printf("     %-16s%-16s%-16s%-16d\n", fgd_name, fgd_host, fgd_ip, base_port);
519                printf("     Enter new Port:[%d] ", base_port);
520                fgets((char *) buffp, 16, stdin);
521                current_port = atoi((char*) buffp);
522                if (current_port < 1025) {
523                    printf("MCP: Be fair please...Ports below 1024 are not a good choice\n");
524                    current_port = base_port;
525                    break;
526                }
527                if (current_port != 0) {
528                    base_port = atoi((char*) buffp);
529                    end_port = base_port;
530                }
531                break;               
532      case 20 : printf("MCP: Current values:\n");
533                printf("     Deamon          Host            IP              Port\n");
534                printf("     %-16s%-16s%-16s%-16d\n", fgd_name, fgd_host, fgd_ip, base_port);
535                printf("     -----------------------------------------------------\n");
536                printf("     Callsign        Host            IP              Port\n");
537                printf("     %-16s%-16s%-16s%-16d\n", fgd_callsign, src_host, fgd_mcp_ip, base_port);
538                printf("                Lat     Lon     Alt     Speed    Roll    Pitch    Yaw\n");
539                printf("     %-8s % 7.3f % 7.3f % 7.3f % 7.3f % 7.3f % 7.3f % 7.3f\n", fgd_callsign, boss->latf,
540                             boss->lonf, boss->altf, boss->speedf, boss->rollf, boss->pitchf, boss->yawf);
541                printf("     -----------------------------------------------------\n");                            
542                printf("     Pilot list:\n");
543                test = head->next;
544                while (test != tail) {
545                printf("     Callsign        Host\n");
546                printf("     %-16s%-16s\n", test->callsign, test->ipadr);
547                printf("                Lat     Lon     Alt     Speed    Roll    Pitch    Yaw\n");
548                printf("     %-8s % 7.3f % 7.3f % 7.3f % 7.3f % 7.3f % 7.3f % 7.3f\n", test->callsign, test->latf,
549                             test->lonf, test->altf, test->speedf, test->rollf, test->pitchf, test->yawf);
550                test = test->next;
551                }
552                printf("     -----------------------------------------------------\n");
553                
554                break;               
555      case 21 : printf("MCP: Enter your callsign, Pilot ");
556                fgets((char *) fgd_callsign, 32, stdin);
557                fgd_callsign[ strlen(fgd_callsign) - 1 ] = 0;
558                break;
559      case 42 : printf("MCP: Commands available:\n 0   Scan for fgd\n 1   Register\n");
560                printf(" 2   Show registered\n 3   Send MSG\n 4   Send MSG to ALL\n");
561                printf(" 5   Push Data to fgd\n 6   Pop Data from fgd\n");
562                printf(" 8   Unregister from fgd\n 9   Shutdown fgd\n");
563                printf("10   Set deamon HOST\n11   Set deamon PORT\n");
564                printf("20   Show values\n21   Set own callsign\n");
565 //               printf("31   Set deamon PORT\n");
566                printf("98   Stress test\n");
567                printf("99   Quit Master Control Program (not recommended)\n");
568                break;
569      case 98 : printf("MCP: Stress test ");
570                fgd_loss = 0;
571                list_search(fgd_mcp_ip);
572                other = act->next;
573                printf("other-ip %s\n", other->ipadr);
574                sleep(3);
575                for ( j=1; j<10000; j++) {
576                  boss->latf += 0.001;
577                  fgd_send_com( "5", src_host);
578                  fgd_send_com( "6", src_host);
579                  printf("other lat:%7.3f  boss lat:%7.3f\n", other->latf, boss->latf);
580                  if (fabs( (double) boss->latf - (double) other->latf ) > 0.001) {
581                    printf("other lat:%7.3f  boss lat:%7.3f\n", other->latf, boss->latf);
582                    fgd_loss++;
583                  }
584                }
585                printf(" Packets lost: %d\n", fgd_loss);
586                break;
587      case 99 : printf("MCP: Good bye...\n");
588                break;
589      default:  printf("MCP: ???\n");
590      }
591    }
592    // fgd_send_com( argv[5], argv[6]);
593    free(buffp);
594    free(fgd_job);     
595    free(fgd_host);
596    free(fgd_callsign);
597    free(fgd_name);
598    free(fgd_ip);
599    free(fgd_mcp_ip);
600    free(fgfs_host);
601    free(fgfs_pilot);
602    free(src_host);
603    free(fgd_txt);
604    exit(0);
605 }