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