Пример #1
0
bool
Transporter::connect_client(NDB_SOCKET_TYPE sockfd) {

  if(m_connected)
    return true;

  if (sockfd == NDB_INVALID_SOCKET)
    return false;

  DBUG_ENTER("Transporter::connect_client");

  DBUG_PRINT("info",("port %d isMgmConnection=%d",m_s_port,isMgmConnection));

  SocketOutputStream s_output(sockfd);
  SocketInputStream s_input(sockfd);

  // send info about own id
  // send info about own transporter type

  s_output.println("%d %d", localNodeId, m_type);
  // get remote id
  int nodeId, remote_transporter_type= -1;

  char buf[256];
  if (s_input.gets(buf, 256) == 0) {
    NDB_CLOSE_SOCKET(sockfd);
    DBUG_RETURN(false);
  }

  int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type);
  switch (r) {
  case 2:
    break;
  case 1:
    // we're running version prior to 4.1.9
    // ok, but with no checks on transporter configuration compatability
    break;
  default:
    NDB_CLOSE_SOCKET(sockfd);
    DBUG_RETURN(false);
  }

  DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d",
		      nodeId, remote_transporter_type));

  if (remote_transporter_type != -1)
  {
    if (remote_transporter_type != m_type)
    {
      DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d",
			   m_type, remote_transporter_type));
      NDB_CLOSE_SOCKET(sockfd);
      g_eventLogger.error("Incompatible configuration: transporter type "
			  "mismatch with node %d", nodeId);
      DBUG_RETURN(false);
    }
  }
  else if (m_type == tt_SHM_TRANSPORTER)
  {
    g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId);
  }

  {
    struct sockaddr_in addr;
    SOCKET_SIZE_TYPE addrlen= sizeof(addr);
    getpeername(sockfd, (struct sockaddr*)&addr, &addrlen);
    m_connect_address= (&addr)->sin_addr;
  }

  bool res = connect_client_impl(sockfd);
  if(res){
    m_connected  = true;
    m_errorCount = 0;
  }
  DBUG_RETURN(res);
}
Пример #2
0
/*
 * Name:    record_on_off
 * Purpose: save keystrokes in keystroke buffer
 * Date:    April 1, 1992
 * Passed:  window:  pointer to current window
 * Notes:   -1 in .next field indicates the end of a recording
 *          -1 in .key field indicates the initial, unassigned macro key
 *          STROKE_LIMIT+1 in .next field indicates an unused space.
 */
int  record_on_off( WINDOW *window )
{
register int next;
int  prev;
int  line;
int  key;
int  func;
char line_buff[(MAX_COLS+2)*2]; /* buffer for char and attribute  */

   mode.record = !mode.record;
   if (mode.record == TRUE) {
      line = window->bottom_line;
      show_avail_strokes( );
      save_screen_line( 0, line, line_buff );
      /*
       * press key that will play back recording
       */
      set_prompt( main11, line );

      /*
       * get the candidate macro key and look up the function assigned to it.
       */
      key = getkey( );
      func = getfunc( key );

      /*
       * the key must be an unused, recognized function key or a function
       *  key assigned to a previously defined macro.  we also need room
       *  in the macro structure.
       */
      if (key <= 256 || (func != 0 && func != PlayBack)) {
         /*
          * cannot assign a recording to this key
          */
         error( WARNING, line, main12 );
         mode.record = FALSE;
      } else if (g_status.stroke_count == 0) {
         /*
          * no more room in recording buffer
          */
         error( WARNING, line, main13 );
         mode.record = FALSE;
      } else {

         /*
          * everything is everything so far, just check for a prev macro
          */
         prev = OK;
         if (func == PlayBack) {
            /*
             * overwrite recording (y/n)?
             */
            set_prompt( main14, line );
            if (get_yn( ) == A_NO) {
               prev = ERROR;
               mode.record = FALSE;
            }
         }
         if (prev == OK) {
            g_status.recording_key = key;
            next = macro.first_stroke[key-256];

            /*
             * if key has already been assigned to a macro, clear macro def.
             */
            if (next != STROKE_LIMIT+1) {
               do {
                  prev = next;
                  next = macro.strokes[next].next;
                  macro.strokes[prev].key  = MAX_KEYS+1;
                  macro.strokes[prev].next = STROKE_LIMIT+1;
                  ++g_status.stroke_count;
               } while (next != -1);
               show_avail_strokes( );
            }

            /*
             * find the first open space and initialize
             */
            for (next=0; macro.strokes[next].next != STROKE_LIMIT+1;)
               next++;
            macro.first_stroke[key-256] = next;
            macro.strokes[next].key  = -1;
            macro.strokes[next].next = -1;
            key_func.key[key-256] = PlayBack;
            /*
             * recording
             */
            s_output( main15, g_display.mode_line, 22,
                      g_display.mode_color | 0x80 );
         }
      }
      restore_screen_line( 0, line, line_buff );
   }

   /*
    * the flashing "Recording" and the stroke count write over the modes.
    *  when we get thru defining a macro, redisplay the modes.
    */
   if (mode.record == FALSE) {
      memset( line_buff, ' ', 36 );
      line_buff[36] = '\0';
      s_output( line_buff, g_display.mode_line, 22, g_display.mode_color );
      show_tab_modes( );
      show_indent_mode( );
      show_sync_mode( );
      show_search_case( );
      show_wordwrap_mode( );

      /*
       * let's look at the macro.  if the first .key of the macro is
       *  still -1, which is the initial unassigned key in a macro, reset
       *  the macro so other keys may be assigned to this node.
       */
      key = g_status.recording_key;
      if (key != 0) {
         next = macro.first_stroke[key-256];
         if (macro.strokes[next].key == -1) {
            macro.strokes[next].key  = MAX_KEYS+1;
            macro.strokes[next].next = STROKE_LIMIT+1;
            macro.first_stroke[key-256] = STROKE_LIMIT+1;
            if (getfunc( key ) == PlayBack)
               key_func.key[key-256] = 0;
         }
      }
      g_status.recording_key = 0;
   }
   return( OK );
}
Пример #3
0
bool
TransporterRegistry::connect_server(NDB_SOCKET_TYPE sockfd)
{
  DBUG_ENTER("TransporterRegistry::connect_server");

  // read node id from client
  // read transporter type
  int nodeId, remote_transporter_type= -1;
  SocketInputStream s_input(sockfd);
  char buf[256];
  if (s_input.gets(buf, 256) == 0) {
    DBUG_PRINT("error", ("Could not get node id from client"));
    DBUG_RETURN(false);
  }
  int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type);
  switch (r) {
  case 2:
    break;
  case 1:
    // we're running version prior to 4.1.9
    // ok, but with no checks on transporter configuration compatability
    break;
  default:
    DBUG_PRINT("error", ("Error in node id from client"));
    DBUG_RETURN(false);
  }

  DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d",
		      nodeId,remote_transporter_type));

  //check that nodeid is valid and that there is an allocated transporter
  if ( nodeId < 0 || nodeId >= (int)maxTransporters) {
    DBUG_PRINT("error", ("Node id out of range from client"));
    DBUG_RETURN(false);
  }
  if (theTransporters[nodeId] == 0) {
      DBUG_PRINT("error", ("No transporter for this node id from client"));
      DBUG_RETURN(false);
  }

  //check that the transporter should be connected
  if (performStates[nodeId] != TransporterRegistry::CONNECTING) {
    DBUG_PRINT("error", ("Transporter in wrong state for this node id from client"));
    DBUG_RETURN(false);
  }

  Transporter *t= theTransporters[nodeId];

  // send info about own id (just as response to acknowledge connection)
  // send info on own transporter type
  SocketOutputStream s_output(sockfd);
  s_output.println("%d %d", t->getLocalNodeId(), t->m_type);

  if (remote_transporter_type != -1)
  {
    if (remote_transporter_type != t->m_type)
    {
      DBUG_PRINT("error", ("Transporter types mismatch this=%d remote=%d",
			   t->m_type, remote_transporter_type));
      g_eventLogger.error("Incompatible configuration: Transporter type "
			  "mismatch with node %d", nodeId);

      // wait for socket close for 1 second to let message arrive at client
      {
	fd_set a_set;
	FD_ZERO(&a_set);
	FD_SET(sockfd, &a_set);
	struct timeval timeout;
	timeout.tv_sec  = 1; timeout.tv_usec = 0;
	select(sockfd+1, &a_set, 0, 0, &timeout);
      }
      DBUG_RETURN(false);
    }
  }
  else if (t->m_type == tt_SHM_TRANSPORTER)
  {
    g_eventLogger.warning("Unable to verify transporter compatability with node %d", nodeId);
  }

  // setup transporter (transporter responsible for closing sockfd)
  t->connect_server(sockfd);

  DBUG_RETURN(true);
}
Пример #4
0
int
main(int argc, const char **argv)
{
	struct commandline cmd;

	memset(&cmd, 0, sizeof (struct commandline));
	clear_args();
	if (!parseargs(argc, argv, &cmd))
		usage();
	/*
	 * Only the client and server side stubs are likely to be customized,
	 *  so in that case only, check if the outfile exists, and if so,
	 *  print an error message and exit.
	 */
	if (cmd.Ssflag || cmd.Scflag || cmd.makefileflag)
		checkfiles(cmd.infile, cmd.outfile);
	else
		checkfiles(cmd.infile, NULL);

	if (cmd.cflag) {
		c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
	} else if (cmd.hflag) {
		h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile,
		    cmd.hflag);
	} else if (cmd.lflag) {
		l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile);
	} else if (cmd.sflag || cmd.mflag || (cmd.nflag)) {
		s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND,
			cmd.outfile, cmd.mflag, cmd.nflag);
	} else if (cmd.tflag) {
		t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile);
	} else if  (cmd.Ssflag) {
		svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND,
			cmd.outfile);
	} else if (cmd.Scflag) {
		clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND,
			    cmd.outfile);
	} else if (cmd.makefileflag) {
		mkfile_output(&cmd);
	} else {
		/* the rescans are required, since cpp may effect input */
		c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
		reinitialize();
		h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h", cmd.hflag);
		reinitialize();
		l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
		reinitialize();
		if (inetdflag || !tirpcflag)
			s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
			"_svc.c", cmd.mflag, cmd.nflag);
		else
			s_output(allnc, allnv, cmd.infile, "-DRPC_SVC",
				EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
		if (tblflag) {
			reinitialize();
			t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
		}

		if (allfiles) {
			reinitialize();
			svc_output(cmd.infile, "-DRPC_SERVER", EXTEND,
				"_server.c");
			reinitialize();
			clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND,
				"_client.c");

		}
		if (allfiles || (cmd.makefileflag == 1)){
			reinitialize();
			mkfile_output(&cmd);
		}
	}

	exit(nonfatalerrors);
	/* NOTREACHED */
}
Пример #5
0
bool
Transporter::connect_client(NDB_SOCKET_TYPE sockfd) {

  DBUG_ENTER("Transporter::connect_client(sockfd)");

  if(m_connected)
  {
    DBUG_PRINT("error", ("Already connected"));
    DBUG_RETURN(true);
  }

  if (!my_socket_valid(sockfd))
  {
    DBUG_PRINT("error", ("Socket " MY_SOCKET_FORMAT " is not valid",
                         MY_SOCKET_FORMAT_VALUE(sockfd)));
    DBUG_RETURN(false);
  }

  DBUG_PRINT("info",("server port: %d, isMgmConnection: %d",
                     m_s_port, isMgmConnection));

  // Send "hello"
  DBUG_PRINT("info", ("Sending own nodeid: %d and transporter type: %d",
                      localNodeId, m_type));
  SocketOutputStream s_output(sockfd);
  if (s_output.println("%d %d", localNodeId, m_type) < 0)
  {
    DBUG_PRINT("error", ("Send of 'hello' failed"));
    NDB_CLOSE_SOCKET(sockfd);
    DBUG_RETURN(false);
  }

  // Read reply
  DBUG_PRINT("info", ("Reading reply"));
  char buf[256];
  SocketInputStream s_input(sockfd);
  if (s_input.gets(buf, 256) == 0)
  {
    DBUG_PRINT("error", ("Failed to read reply"));
    NDB_CLOSE_SOCKET(sockfd);
    DBUG_RETURN(false);
  }

  // Parse reply
  int nodeId, remote_transporter_type= -1;
  int r= sscanf(buf, "%d %d", &nodeId, &remote_transporter_type);
  switch (r) {
  case 2:
    break;
  case 1:
    // we're running version prior to 4.1.9
    // ok, but with no checks on transporter configuration compatability
    break;
  default:
    DBUG_PRINT("error", ("Failed to parse reply"));
    NDB_CLOSE_SOCKET(sockfd);
    DBUG_RETURN(false);
  }

  DBUG_PRINT("info", ("nodeId=%d remote_transporter_type=%d",
		      nodeId, remote_transporter_type));

  // Check nodeid
  if (nodeId != remoteNodeId)
  {
    g_eventLogger->error("Connected to wrong nodeid: %d, expected: %d",
                         nodeId, remoteNodeId);
    NDB_CLOSE_SOCKET(sockfd);
    DBUG_RETURN(false);
  }

  // Check transporter type
  if (remote_transporter_type != -1 &&
      remote_transporter_type != m_type)
  {
    g_eventLogger->error("Connection to node: %d uses different transporter "
                         "type: %d, expected type: %d",
                         nodeId, remote_transporter_type, m_type);
    NDB_CLOSE_SOCKET(sockfd);
    DBUG_RETURN(false);
  }

  // Cache the connect address
  my_socket_connect_address(sockfd, &m_connect_address);

  if (!connect_client_impl(sockfd))
    DBUG_RETURN(false);

  m_connected = true;

  DBUG_RETURN(true);
}
Пример #6
0
int
main(int argc, char *argv[])
{
    struct commandline cmd;

#ifdef AFS_NT40_ENV
    /* initialize CPP with the correct pre-processor for Windows */
    CPP = getenv("RXGEN_CPPCMD");
    if (!CPP)
	CPP = "cl /EP /C /nologo";
#endif /* AFS_NT40_ENV */

#ifdef	AFS_AIX32_ENV
    /*
     * The following signal action for AIX is necessary so that in case of a
     * crash (i.e. core is generated) we can include the user's data section
     * in the core dump. Unfortunately, by default, only a partial core is
     * generated which, in many cases, isn't too useful.
     */
    struct sigaction nsa;

    sigemptyset(&nsa.sa_mask);
    nsa.sa_handler = SIG_DFL;
    nsa.sa_flags = SA_FULLDUMP;
    sigaction(SIGSEGV, &nsa, NULL);
#endif
    reinitialize();
    if (!parseargs(argc, argv, &cmd)) {
	f_print(stderr, "usage: %s infile\n", cmdname);
	f_print(stderr,
		"       %s [-c | -h | -l | -m | -C | -S | -r | -b | -k | -R | -p | -d | -z | -u] [-Pprefix] [-Idir] [-o outfile] [infile]\n",
		cmdname);
	f_print(stderr, "       %s [-s udp|tcp]* [-o outfile] [infile]\n",
		cmdname);
	exit(1);
    }
    OutFileFlag = cmd.outfile;
    if (OutFileFlag)
	strcpy(OutFile, cmd.outfile);
    if (cmd.cflag) {
	OutFileFlag = NULL;
	c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile, 0);
    } else if (cmd.hflag) {
	h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile, 0);
    } else if (cmd.lflag) {
	l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile);
    } else if (cmd.sflag || cmd.mflag) {
	s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND, cmd.outfile,
		 cmd.mflag);
    } else if (cmd.Cflag) {
	OutFileFlag = NULL;
	C_output(cmd.infile, "-DRPC_CLIENT", !EXTEND, cmd.outfile, 1);
    } else if (cmd.Sflag) {
	OutFileFlag = NULL;
	S_output(cmd.infile, "-DRPC_SERVER", !EXTEND, cmd.outfile, 1);
    } else {
	if (OutFileFlag && (strrchr(OutFile, '.') == NULL))
	    strcat(OutFile, ".");
	if (cmd.rflag) {
	    C_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_CLIENT",
		     EXTEND, ".cs.c", 1);
	    reinitialize();
	    S_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_SERVER",
		     EXTEND, ".ss.c", 1);
	    reinitialize();
	} else {
	    reinitialize();
	    c_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_XDR",
		     EXTEND, ".xdr.c", 0);
	    reinitialize();
	    h_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_HDR",
		     EXTEND, ".h", 0);
	    reinitialize();
	    C_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_CLIENT",
		     EXTEND, ".cs.c", 1);
	    reinitialize();
	    S_output((OutFileFlag ? OutFile : cmd.infile), "-DRPC_SERVER",
		     EXTEND, ".ss.c", 1);
	    reinitialize();
	}
    }
    if (fin && pclose_fin) {
	/* the cpp command we called returned a non-zero exit status */
	if (pclose(fin)) {
	    crash();
	}
    }
    exit(0);
}
Пример #7
0
void GeneralTab::outputChanged(int output)
{
	s_output(output);
	updateVideoOutput();
}
Пример #8
0
/*
 * Name:    select_file
 * Purpose: To let user select a file from dir list
 * Date:    February 13, 1992
 * Passed:  flist: pointer to list of files
 *          stem:  base directory
 *          dir:   directory display stuff
 * Notes:   let user move thru the file names with the cursor keys
 */
int  select_file( FTYPE *flist, char *stem, DIRECTORY *dir )
{
int  ch;                /* input character from user */
int  func;              /* function of character input by user */
int  fno;               /* index into flist of the file under cursor */
int  goodkey;           /* is key a recognized function key? */
int  r;                 /* current row of cursor */
int  c;                 /* current column of cursor */
int  offset;            /* offset into file list */
int  stop;              /* stop indicator */
int  stem_len;          /* stem length */
int  color;             /* color of help screen */
int  file_color;        /* color of current file */
int  change;            /* boolean, hilite another file? */
int  oldr;              /* old row */
int  oldc;              /* old column */
char asize[20];         /* ascii file size */
char blank[20];         /* blank out file names */

   /*
    * initial everything.
    */
   memset( blank, ' ', 12 );
   blank[12] = '\0';
   c = r = 1;
   ch = fno = offset = 0;
   color = g_display.help_color;
   file_color = g_display.hilited_file;
   goodkey = TRUE;
   stop = FALSE;
   stem_len = strlen( stem );
   s_output( stem, dir->row+1, dir->col+19, color );
   s_output( flist[fno].fname, dir->row+1, dir->col+19+stem_len, color );
   ltoa( flist[fno].fsize, asize, 10 );
   s_output( blank, dir->row+2, dir->col+19, color );
   s_output( asize, dir->row+2, dir->col+19, color );
   itoa( dir->cnt,  asize, 10 );
   s_output( blank, dir->row+2, dir->col+57, color );
   s_output( asize, dir->row+2, dir->col+57, color );
   xygoto( (c-1)*14+dir->col+2, r+dir->row+3 );
   hlight_line( (c-1)*14+dir->col+2, r+dir->row+3, 12, file_color );
   change = FALSE;
   while (stop == FALSE) {
      oldr = r;
      oldc = c;
      ch = getkey( );
      func = getfunc( ch );

      /*
       * User may have redefined the Enter and ESC keys.  Make the Enter key
       *  perform a Rturn in this function. Make the ESC key do an AbortCommand.
       */
      if (ch == RTURN)
         func = Rturn;
      else if (ch == ESC)
         func = AbortCommand;

      switch (func) {
         case Rturn       :
         case NextLine    :
         case BegNextLine :
            stop = TRUE;
            break;
         case AbortCommand :
            stop = TRUE;
            break;
         case LineUp :
            if (r > 1) {
               change = TRUE;
               --r;
            } else {
               r = dir->lines;
               change = TRUE;
               if (offset == 0 || c > 1) {
                  if (c > 1)
                     --c;
               } else if (dir->vcols > 0 && offset > 0 && c == 1) {
                  /*
                   * recalculate the dir display stuff.
                   */
                  offset -= dir->lines;
                  recalculate_dir( dir, flist, offset );
               }
            }
            goodkey = TRUE;
            break;
         case LineDown :
            if (r < dir->prow) {
               change = TRUE;
               ++r;
            } else if (r < dir->lines && c != dir->cols) {
               change = TRUE;
               ++r;
            } else {
               change = TRUE;
               r = 1;
               if (offset == dir->vcols * dir->lines || c < dir->cols) {
                  if (c < dir->cols)
                     ++c;
               } else if (dir->vcols > 0 && offset < dir->vcols * dir->lines &&
                         c == dir->cols) {
                  offset += dir->lines;
                  recalculate_dir( dir, flist, offset );
               }
            }
            goodkey = TRUE;
            break;
         case CharLeft :
            if (offset == 0 || c > 1) {
               if (c > 1) {
                  change = TRUE;
                  --c;
               }
            } else if (dir->vcols > 0 && offset > 0 && c == 1) {
               change = TRUE;

               /*
                * recalculate the dir display stuff.
                */
               offset -= dir->lines;
               recalculate_dir( dir, flist, offset );
            }
            goodkey = TRUE;
            break;
         case CharRight :
            if (offset == dir->vcols * dir->lines || c < dir->cols) {
               if (c < dir->cols) {
                  change = TRUE;
                  ++c;
                  if (c == dir->cols) {
                     if ( r > dir->prow)
                        r = dir->prow;
                  }
               }
            } else if (dir->vcols > 0 && offset < dir->vcols * dir->lines &&
                         c == dir->cols) {
               change = TRUE;
               offset += dir->lines;
               recalculate_dir( dir, flist, offset );
               if (r > dir->prow)
                  r = dir->prow;
            }
            goodkey = TRUE;
            break;
         case BegOfLine :
            change = TRUE;
            c = r = 1;
            goodkey = TRUE;
            break;
         case EndOfLine :
            change = TRUE;
            r = dir->prow;
            c = dir->cols;
            goodkey = TRUE;
            break;
         case ScreenDown :
            change = TRUE;
            r = (c == dir->cols) ? r = dir->prow : dir->lines;
            goodkey = TRUE;
            break;
         case ScreenUp :
            change = TRUE;
            r = 1;
            goodkey = TRUE;
            break;
         default :
            break;
      }
      if (goodkey) {
         s_output( blank, dir->row+1, dir->col+19+stem_len, color );
         fno = offset + (c-1)*dir->lines + (r-1);
         s_output( flist[fno].fname, dir->row+1, dir->col+19+stem_len, color );
         ltoa( flist[fno].fsize, asize, 10 );
         s_output( blank, dir->row+2, dir->col+19, color );
         s_output( asize, dir->row+2, dir->col+19, color );
         xygoto( (c-1)*14+dir->col+2, r+dir->row+3 );
         goodkey = FALSE;
         if (change) {
            hlight_line( (oldc-1)*14+dir->col+2, oldr+dir->row+3, 12, color );
            hlight_line( (c-1)*14+dir->col+2, r+dir->row+3, 12, file_color );
            change = FALSE;
         }
      }
   }
   dir->select = fno;
   return( func == AbortCommand ? ERROR : OK );
}
Пример #9
0
/*
 * Name:    differ
 * Purpose: diff text pointers
 * Date:    October 31, 1992
 * Passed:  initial_rcol1:  beginning column to begin diff in window1
 *          initial_rcol2:  beginning column to begin diff in window2
 *          bottom:         line to display diagnostics
 * Notes:   a straight diff on text pointers is simple; however, diffing
 *            with leading spaces and tabs is kinda messy.  let's do the
 *            messy diff.
 */
int  differ( int initial_rcol1, int initial_rcol2, int bottom )
{
int  rcol1;             /* virtual real column on diff window 1 */
int  rcol2;             /* virtual real column on diff window 2 */
int  r1;                /* real real column rcol1 - needed for tabs */
int  r2;                /* real real column rcol2 - needed for tabs */
char c1;                /* character under r1 */
char c2;                /* character under r2 */
int  leading1;          /* adjustment for leading space in window 1 */
int  leading2;          /* adjustment for leading space in window 2 */
int  len1;              /* length of diff1 line */
int  len2;              /* length of diff2 line */
line_list_ptr node1;    /* scratch node in window 1 */
line_list_ptr node2;    /* scratch node in window 2 */
text_ptr diff1;         /* scratch text ptr in window 1 */
text_ptr diff2;         /* scratch text ptr in window 2 */
long rline1;            /* real line number of diff pointer 1 */
long rline2;            /* real line number of diff pointer 2 */
long bin_offset1;       /* binary offset of diff pointer 1 */
long bin_offset2;       /* binary offset of diff pointer 2 */
int  len;               /* line length variable */
register int tabs;      /* local variable for mode.inflate_tabs, T or F */
char line_buff[(MAX_COLS+1)*2];  /* buffer for char and attribute  */

   /*
    * initialize the text pointers and the initial column.  skip any
    *  initial blank lines.
    */
   rline1 = diff.rline1;
   rline2 = diff.rline2;
   node1 = diff.d1;
   node2 = diff.d2;
   bin_offset1 = diff.bin_offset1;
   bin_offset2 = diff.bin_offset2;
   tabs  = mode.inflate_tabs;
   if (diff.blank_lines) {
      while (node1->len != EOF  && is_line_blank( node1->line, node1->len )) {
         bin_offset1 += node1->len;
         node1 = node1->next;
         ++rline1;
         initial_rcol1 = 0;
      }
      while (node2->len != EOF  && is_line_blank( node2->line , node2->len)) {
         bin_offset2 += node2->len;
         node2 = node2->next;
         ++rline2;
         initial_rcol2 = 0;
      }
   }

   /*
    * if everything is everything, initialize the diff variables and diff.
    */
   if (node1->len != EOF  &&  node2->len != EOF) {
      diff1 = node1->line;
      diff2 = node2->line;
      rcol1 = initial_rcol1;
      rcol2 = initial_rcol2;
      len1  = node1->len;
      len2  = node2->len;

      assert( rcol1 >= 0 );
      assert( rcol1 < MAX_LINE_LENGTH );
      assert( rcol2 >= 0 );
      assert( rcol2 < MAX_LINE_LENGTH );
      assert( len1 >= 0 );
      assert( len1 < MAX_LINE_LENGTH );
      assert( len2 >= 0 );
      assert( len2 < MAX_LINE_LENGTH );

      /*
       * if cursors are past EOL, move them back to EOL.
       */
      len = find_end( diff1, len1 );
      if (rcol1 > len)
         rcol1 = len;
      len = find_end( diff2, len2 );
      if (rcol2 > len)
         rcol2 = len;

      /*
       * if skip leading space, make sure our cursors start on first non-space.
       */
      if (diff.leading) {
         leading1 = skip_leading_space( diff1, len1 );
         leading2 = skip_leading_space( diff2, len2 );
         if (tabs) {
            leading1 = detab_adjust_rcol( diff1, leading1 );
            leading2 = detab_adjust_rcol( diff2, leading2 );
         }
         if (rcol1 < leading1)
            rcol1 = leading1;
         if (rcol2 < leading2)
            rcol2 = leading2;
      }

      /*
       * we now have a valid rcol for the diff start, we may need to adjust
       *   for tabs, though.
       */
      assert( rcol1 >= 0 );
      assert( rcol1 < MAX_LINE_LENGTH );
      assert( rcol2 >= 0 );
      assert( rcol2 < MAX_LINE_LENGTH );

      r1 =  tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
      r2 =  tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;

      assert( r1 >= 0 );
      assert( r1 <= len1 );
      assert( r2 >= 0 );
      assert( r2 <= len2 );
      assert( r1 <= rcol1 );
      assert( r2 <= rcol2 );

      s_output( diff_message, g_display.mode_line, 67, g_display.diag_color );
      while (node1->len != EOF  &&  node2->len != EOF  &&
                         !g_status.control_break) {

         /*
          * look at each character in each diff window
          */
         c1 = (char)(r1 < len1 ? *(diff1 + r1)  : 0);
         c2 = (char)(r2 < len2 ? *(diff2 + r2)  : 0);

         /*
          *  tabs == space
          */
         if (tabs) {
            if (c1 == '\t')
               c1 = ' ';
            if (c2 == '\t')
               c2 = ' ';
         }

         /*
          * skip spaces, if needed
          */
         if (diff.all_space) {
            while (c1 == ' '  &&  r1 < len1) {
               ++rcol1;
               r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
               c1 =  (char)(r1 < len1  ?  *(diff1 + r1) :  0);
               if (c1 == '\t'  &&  tabs)
                  c1 = ' ';
            }
            while (c2 == ' '  &&  r2 < len2) {
               ++rcol2;
               r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;
               c2 =  (char)(r2 < len2  ? *(diff2 + r2) : 0);
               if (c2 == '\t'  &&  tabs)
                  c2 = ' ';
            }
         }

         /*
          * if one of the node pointers has come to EOL, move to next
          *   diff line.
          */
         if (diff.ignore_eol) {
            if (r1 >= len1) {
               node1 = skip_eol( node1, &r1, &rcol1, &rline1, &bin_offset1 );
               len1  = node1->len;
               if (len1 != EOF) {
                  diff1 = node1->line;
                  c1 =  (char)(r1 < len1  ?  *(diff1 + r1) : 0);
                  if (c1 == '\t'  &&  tabs)
                     c1 = ' ';
               }
            }
            if (r2 >= len2) {
               node2 = skip_eol( node2, &r2, &rcol2, &rline2, &bin_offset2 );
               len2  = node2->len;
               if (len2 != EOF) {
                  diff2 = node2->line;
                  c2 =  (char)(r2 < len2  ? *(diff2 + r2)  :  0);
                  if (c2 == '\t'  &&  tabs)
                     c2 = ' ';
               }
            }
         }

         /*
          * convert the characters to lower case, if needed.
          */
         if (mode.search_case == IGNORE) {
            c1 = (char)tolower( c1 );
            c2 = (char)tolower( c2 );
         }

         /*
          * diff each character in the diff lines until we reach EOL
          */
         while (r1 < len1  && r2 < len2) {
            if (c1 == c2) {
               if (diff.all_space) {
                  do {
                     ++rcol1;
                     r1 = tabs ? entab_adjust_rcol( diff1,len1,rcol1 ) : rcol1;
                     c1 =  (char)(r1 < len1  ?  *(diff1 + r1)  :  0);
                     if (c1 == '\t'  &&  tabs)
                        c1 = ' ';
                  } while (c1 == ' '  &&  r1 < len1);
                  do {
                     ++rcol2;
                     r2 = tabs ? entab_adjust_rcol( diff2,len2,rcol2 ) : rcol2;
                     c2 =  (char)(r2 < len2  ?  *(diff2 + r2)  :  0);
                     if (c2 == '\t'  &&  tabs)
                        c2 = ' ';
                  } while (c2 == ' '  &&  r2 < len2);
               } else {
                  ++rcol1;
                  ++rcol2;
                  r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
                  r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;
                  c1 =  (char)(r1 < len1  ?  *(diff1 + r1)  :  0);
                  c2 =  (char)(r2 < len2  ?  *(diff2 + r2)  :  0);
                  if (tabs) {
                     if (c1 == '\t')
                        c1 = ' ';
                     if (c2 == '\t')
                        c2 = ' ';
                  }
               }
               if (diff.ignore_eol) {
                  if (r1 >= len1) {
                     node1 = skip_eol(node1, &r1, &rcol1, &rline1,&bin_offset1);
                     len1  = node1->len;
                     if (len1 != EOF) {
                        diff1 = node1->line;
                        c1 =  (char)(r1 < len1  ?  *(diff1 + r1)  : 0);
                        if (c1 == '\t'  &&  tabs)
                           c1 = ' ';
                     }
                  }
                  if (r2 >= len2) {
                     node2 = skip_eol(node2, &r2, &rcol2, &rline2,&bin_offset2);
                     len2  = node2->len;
                     if (len2 != EOF) {
                        diff2 = node2->line;
                        c2 = (char)(r2 < len2  ? *(diff2 + r2)  :  0);
                        if (c2 == '\t'  &&  tabs)
                           c2 = ' ';
                     }
                  }
               }
               if (mode.search_case == IGNORE) {
                  c1 = (char)tolower( c1 );
                  c2 = (char)tolower( c2 );
               }
            } else {

               /*
                * when we show the diff, use rcol1 and rcol2, as
                *   find_adjust does not adjust rcol for tabs.
                */
               update_line( diff.w1 );
               diff.w1->bin_offset = bin_offset1;
               find_adjust( diff.w1, node1, rline1, rcol1 );
               check_virtual_col( diff.w1, rcol1, rcol1 );
               show_diff_window( diff.w1 );
               update_line( diff.w2 );
               diff.w2->bin_offset = bin_offset2;
               bin_offset_adjust( diff.w2, rline2 );
               find_adjust( diff.w2, node2, rline2, rcol2 );
               check_virtual_col( diff.w2, rcol2, rcol2 );
               show_diff_window( diff.w2 );
               s_output( diff_blank, g_display.mode_line, 67,
                         g_display.mode_color );
               return( OK );
            }
         }

         /*
          * if we haven't come to the end of a file buffer, check the last
          *   characters.  see if pointers are at EOL.
          */
         if (node1->len != EOF && node2->len != EOF) {
            if (rcol1 != len1  &&  rcol2 != len2) {
               update_line( diff.w1 );
               diff.w1->bin_offset = bin_offset1;
               find_adjust( diff.w1, node1, rline1, rcol1 );
               show_diff_window( diff.w1 );
               update_line( diff.w2 );
               diff.w2->bin_offset = bin_offset2;
               find_adjust( diff.w2, node2, rline2, rcol2 );
               show_diff_window( diff.w2 );
               s_output( diff_blank, g_display.mode_line, 67,
                         g_display.mode_color );
               return( OK );
            } else {
               node1 = skip_eol( node1, &r1, &rcol1, &rline1, &bin_offset1 );
               len1  = node1->len;
               diff1 = node1->line;
               node2 = skip_eol( node2, &r2, &rcol2, &rline2, &bin_offset2 );
               len2  = node2->len;
               diff2 = node2->line;
            }
         }

         assert( rcol1 >= 0 );
         assert( rcol1 < MAX_LINE_LENGTH );
         assert( rcol2 >= 0 );
         assert( rcol2 < MAX_LINE_LENGTH );
         assert( r1 >= 0 );
         assert( r1 < MAX_LINE_LENGTH );
         assert( r2 >= 0 );
         assert( r2 < MAX_LINE_LENGTH );
         assert( r1 <= rcol1 );
         assert( r2 <= rcol2 );
         if (node1->len == EOF)
            assert( len1 == EOF );
         else {
            assert( len1 >= 0 );
            assert( len1 < MAX_LINE_LENGTH );
         }
         if (node2->len == EOF)
            assert( len2 == EOF );
         else {
            assert( len2 >= 0 );
            assert( len2 < MAX_LINE_LENGTH );
         }
      }
      save_screen_line( 0, bottom, line_buff );
      set_prompt( diff_prompt4, bottom );
      getkey( );
      restore_screen_line( 0, bottom, line_buff );
      s_output( diff_blank, g_display.mode_line, 67, g_display.mode_color );
   }
   return( ERROR );
}
Пример #10
0
/*
 * Name:    setup_directory_window
 * Purpose: set number of rows and cols in directory window
 * Date:    February 13, 1992
 * Passed:  dir: pointer to directory structure
 *          cnt: number of files
 * Notes:   set up stuff we need to know about how to display files.
 */
void setup_directory_window( DIRECTORY *dir, int cnt )
{
int  i;
int  wid;
char temp[MAX_COLS];    /* line to output */

   /*
    * setup the fixed vars used in dir display.
    *    dir->col =      physical upper left column of dir screen
    *    dir->row =      physical upper left row or line of dir screen
    *    dir->wid =      width of physical screen
    *    dir->hgt =      height of physical screen
    *    dir->max_cols   number of columns of files in dir screen
    *    dir->max_lines  number of lines of files in each column in dir screen
    *    dir->cnt        number of files in list
    */
   dir->col = 3;
   dir->row = 5;
   wid = dir->wid = 72;
   dir->hgt = 16;
   dir->max_cols = 5;
   dir->max_lines = 9;
   dir->cnt = cnt;

   /*
    * Find out how many lines in each column are needed to display
    *  matching files.
    */
   dir->lines = dir->cnt / dir->max_cols + (dir->cnt % dir->max_cols ? 1 : 0);
   if (dir->lines > dir->max_lines)
      dir->lines = dir->max_lines;

   /*
    * Find out how many columns of file names we need.
    */
   dir->cols = dir->cnt / dir->lines + (dir->cnt % dir->lines ? 1 : 0);
   if (dir->cols > dir->max_cols)
      dir->cols = dir->max_cols;


   /*
    * Find the maximun number of file names we can display in help screen.
    */
   dir->avail = dir->lines * dir->cols;

   /*
    * Now find the number of file names we do have on the screen.  Every
    *  time we slide the "window", we have to calculate a new nfiles.
    */
   dir->nfiles = dir->cnt > dir->avail ? dir->avail : dir->cnt;

   /*
    * A lot of times, the number of matching files will not fit evenly
    *  in our help screen.  The last column on the right will be partially
    *  filled, hence the variable name prow (partial row).  When there are
    *  more file names than can fit on the screen, we have to calculate
    *  prow every time we slide the "window" of files.
    */
   dir->prow = dir->lines - (dir->avail - dir->nfiles);

   /*
    * Find out how many "virtual" columns of file names we have.  If
    *  all the files can fit in the dir screen, there will be no
    *  virtual columns.
    */
   if (dir->cnt < dir->avail)
      dir->vcols = 0;
   else
      dir->vcols =  (dir->cnt - dir->avail) / dir->max_lines +
                   ((dir->cnt - dir->avail) % dir->max_lines ? 1 : 0);

   /*
    * Find the physical display column in dir screen.
    */
   dir->flist_col[0] = dir->col + 2;
   for (i=1; i<dir->max_cols; i++)
      dir->flist_col[i] = dir->flist_col[i-1] + 14;

   /*
    * Now, draw the borders of the dir screen.
    */
   for (i=0; i < dir->hgt; i++) {
      if (i == 0 || i == dir->hgt-1) {
         memset( temp, 'Ä', wid );
         temp[wid] = '\0';
         if (i == 0) {
            temp[0] = 'Ú';
            temp[wid-1] = '¿';
         } else {
            temp[0] = 'À';
            temp[wid-1] = 'Ù';
         }
      } else {
         memset( temp, ' ', wid );
         temp[wid] = '\0';
         temp[0] = temp[wid-1] = '³';
      }
      s_output( temp, dir->row+i, dir->col, g_display.help_color );
   }

   /*
    * Write headings in help screen.
    */
   s_output( dir4, dir->row+1, dir->col+3, g_display.help_color );
   s_output( dir5, dir->row+2, dir->col+3, g_display.help_color );
   s_output( dir6, dir->row+2, dir->col+44, g_display.help_color );
   s_output( dir7, dir->row+14, dir->col+8, g_display.help_color );
}
Пример #11
0
int
main(int argc, char **argv)
{
	struct commandline cmd;

	(void) memset((char *) &cmd, 0, sizeof(struct commandline));
	clear_args();
	if (!parseargs(argc, argv, &cmd))
		usage();

	if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag ||
		cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag) {
		checkfiles(cmd.infile, cmd.outfile);
	} else
		checkfiles(cmd.infile, NULL);

	if (cmd.cflag) {
		c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
	} else if (cmd.hflag) {
		h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile);
	} else if (cmd.lflag) {
		l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile);
	} else if (cmd.sflag || cmd.mflag || (cmd.nflag)) {
		s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND,
			cmd.outfile, cmd.mflag, cmd.nflag);
	} else if (cmd.tflag) {
		t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile);
	} else if (cmd.Ssflag) {
		svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile);
	} else if (cmd.Scflag) {
		clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile);
	} else {
		/* the rescans are required, since cpp may effect input */
		c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
		reinitialize();
		h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
		reinitialize();
		l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
		reinitialize();
		if (inetdflag || !tirpcflag)
			s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
				"_svc.c", cmd.mflag, cmd.nflag);
		else
			s_output(allnc, allnv, cmd.infile, "-DRPC_SVC",
				EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
		if (tblflag) {
			reinitialize();
			t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
		}
		if (allfiles) {
			reinitialize();
			svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c");
		}
		if (allfiles) {
			reinitialize();
			clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c");
		}
	}
	exit(nonfatalerrors);
	/* NOTREACHED */
}
Пример #12
0
bool
SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd)
{
  DBUG_ENTER("SHM_Transporter::connect_client_impl");
  SocketInputStream s_input(sockfd);
  SocketOutputStream s_output(sockfd);
  char buf[256];

  // Wait for server to create and attach
  DBUG_PRINT("info", ("Wait for server to create and attach"));
  if (s_input.gets(buf, 256) == 0) {
    NDB_CLOSE_SOCKET(sockfd);
    DBUG_PRINT("error", ("Server id %d did not attach",
                remoteNodeId));
    DBUG_RETURN(false);
  }

  if(sscanf(buf, "shm server 1 ok: %d", &m_remote_pid) != 1)
  {
    NDB_CLOSE_SOCKET(sockfd);
    DBUG_RETURN(false);
  }
  
  // Create
  if(!_shmSegCreated){
    if (!ndb_shm_get()) {
      NDB_CLOSE_SOCKET(sockfd);
      DBUG_PRINT("error", ("Failed create of shm seg to node %d",
                  remoteNodeId));
      DBUG_RETURN(false);
    }
    _shmSegCreated = true;
  }

  // Attach
  if(!_attached){
    if (!ndb_shm_attach()) {
      make_error_info(buf, sizeof(buf));
      report_error(TE_SHM_UNABLE_TO_ATTACH_SEGMENT, buf);
      NDB_CLOSE_SOCKET(sockfd);
      DBUG_PRINT("error", ("Failed attach of shm seg to node %d",
                  remoteNodeId));
      DBUG_RETURN(false);
    }
    _attached = true;
  }

  // Send ok to server
  s_output.println("shm client 1 ok: %d", 
		   m_transporter_registry.m_shm_own_pid);
  
  int r= connect_common(sockfd);
  
  if (r) {
    // Wait for ok from server
    DBUG_PRINT("info", ("Wait for ok from server"));
    if (s_input.gets(buf, 256) == 0) {
      NDB_CLOSE_SOCKET(sockfd);
      DBUG_PRINT("error", ("No ok from server node %d",
                  remoteNodeId));
      DBUG_RETURN(false);
    }
    // Send ok to server
    s_output.println("shm client 2 ok");
    DBUG_PRINT("info", ("Successfully connected client to node %d",
                remoteNodeId)); 
  }

  NDB_CLOSE_SOCKET(sockfd);
  DBUG_RETURN(r);
}
Пример #13
0
void new_assignment_help( HELP_WINDOW *hw, char *help[],
                          struct screen *help_heading, int *ch )
{
int col, row, i;
int update_name, change_color, draw_page;

   save_and_draw( hw, help_heading, &w_ptr );
   show_func_list( hw, help );

   col = hw->ulft_col + hw->dply_col;
   row = hw->ulft_row + hw->dply_row + hw->v_row;
   change_color = TRUE;
   *ch = 0;
   while (*ch!=RTURN && *ch!=ESC) {
      draw_page = FALSE;
      position_cursor( hw, hw->line_length, &update_name, &change_color, ch );
      switch (*ch) {
         case PGUP :
            if (hw->select > hw->avail_lines-1) {
               hw->select = hw->select - hw->avail_lines;
               if (hw->v_row > hw->select)
                  hw->select = hw->v_row;
               draw_page = TRUE;
            } else if (hw->select - hw->v_row > 0) {
               hw->select = hw->v_row;
               draw_page = TRUE;
            }
            break;
         case PGDN :
            if (hw->select + hw->avail_lines < hw->num_entries) {
               hw->select = hw->select + hw->avail_lines;
               draw_page = TRUE;
            } else if (hw->select + hw->avail_lines - hw->v_row <
                                                         hw->num_entries) {
               hw->select = hw->num_entries - 1;
               draw_page = TRUE;
            }
            if ((hw->num_entries - 1) - hw->select <
                                              hw->avail_lines && draw_page) {
               i = row - hw->v_row;
               scroll_window( 0, i, col, i+hw->avail_lines-1,
                              col+hw->line_length, NORMAL );
            }
            break;
      }
      if (draw_page == TRUE) {
         show_func_list( hw, help );
         update_name = TRUE;
         change_color = TRUE;
      }
      row = hw->ulft_row + hw->dply_row + hw->v_row;
      if (update_name)
         s_output( help[hw->select], row, col, NORMAL );
      if (change_color)
         hlight_line( col, row, hw->line_length, cfg.attr );
      *ch = getkey( );
      change_color = FALSE;
   }
   window_control( &w_ptr, RESTORE, hw->ulft_col, hw->ulft_row,
                   hw->total_col, hw->total_row );
   if (*ch != RTURN)
      *ch = 0;
}
Пример #14
0
void master_help( HELP_WINDOW *hw, KEY_DEFS *help, struct screen *help_heading,
                  char *t, int *ch )
{
FILE *fp;               
int col, row, i, j;
int update_name, change_color, draw_page;
char str[80];
char *blank = "                                                 ";
char temp[20];
HELP_WINDOW hw_k;

   xygoto( -1, -1 );
   save_and_draw( hw, help_heading, &w_ptr );
   show_key_def_list( hw, help );

   col = hw->ulft_col + hw->dply_col;
   row = hw->ulft_row + hw->dply_row + hw->v_row;
   change_color = TRUE;
   *ch = 0;
   while (*ch!=F3 && *ch != F10 && *ch!=ESC) {
      draw_page = FALSE;
      position_cursor( hw, hw->line_length, &update_name, &change_color, ch );
      switch (*ch) {
         case PGUP :
            if (hw->select > hw->avail_lines-1) {
               hw->select = hw->select - hw->avail_lines;
               if (hw->v_row > hw->select)
                  hw->select = hw->v_row;
               draw_page = TRUE;
            } else if (hw->select - hw->v_row > 0) {
               hw->select = hw->v_row;
               draw_page = TRUE;
            }
            break;
         case PGDN :
            if (hw->select + hw->avail_lines < hw->num_entries) {
               hw->select = hw->select + hw->avail_lines;
               draw_page = TRUE;
            } else if (hw->select + hw->avail_lines - hw->v_row <
                                                         hw->num_entries) {
               hw->select = hw->num_entries - 1;
               draw_page = TRUE;
            }
            if ((hw->num_entries - 1) - hw->select <
                                              hw->avail_lines && draw_page) {
               i = row - hw->v_row;
               scroll_window( 0, i, col, i+hw->avail_lines-1,
                              col+hw->line_length, NORMAL );
            }
            break;
         case F5 :
            hw_k.dply_col = 2;
            hw_k.dply_row = 3;
            hw_k.line_length = 33;
            hw_k.avail_lines = 6;
            hw_k.v_row = 0;
            hw_k.select = 0;
            hw_k.num_entries = NUM_FUNC;
            hw_k.ulft_col = 20;
            hw_k.ulft_row = row + 1;
            if (hw_k.ulft_row > 12)
               hw_k.ulft_row = row - 12;
            hw_k.total_col = 37;
            hw_k.total_row = 12;
            new_assignment_help( &hw_k, avail_func, func_head, ch );
            if (*ch == RTURN) {
               help[hw->select].key[0] = '*';
               help[hw->select].func_index = (unsigned char)hw_k.select;
               s_output( help[hw->select].key, row, col, cfg.attr );
               s_output( "                     ", row, col+31, cfg.attr );
               s_output( avail_func[help[hw->select].func_index],
                         row, col+31, cfg.attr );
               *ch = 0;
            }
            break;
         case F7 :
            hw_k.ulft_col = 14;
            hw_k.ulft_row = 10;
            hw_k.total_col = 52;
            hw_k.total_row = 5;
            save_and_draw( &hw_k, file_head, &w_ptr );
            xygoto( hw_k.ulft_col+28, hw_k.ulft_row+2 );
            gets( str );
            j = TRUE;
            if ((i = access( str, EXIST )) == 0) {
               s_output( blank, hw_k.ulft_row+2, hw_k.ulft_col+1, NORMAL );
               s_output( "OK to overwrite exiting file (y/n)?",
                          hw_k.ulft_row+2, hw_k.ulft_col+1, NORMAL );
               xygoto( hw_k.ulft_col+38, hw_k.ulft_row+2 );
               i = getkey( );
               while (i != 'Y' && i != 'y' && i != 'N' && i != 'n')
                  i = getkey( );
               if (i == 'n' || i == 'N')
                  j = FALSE;
            }
            xygoto( -1, -1 );
            if (j == TRUE && (fp = fopen( str, "w" )) != NULL) {
               for (i=0; i<hw->num_entries && j; i++) {
                  fprintf( fp, " %22s  = ", help[i].key+3 );
                  fprintf( fp, "  %s\n",  avail_func[help[i].func_index] );
               }
               fclose( fp );
            } else {
               s_output( blank, hw_k.ulft_row+2, hw_k.ulft_col+1, NORMAL );
               s_output( "Cannot open file.  Press any key to contine.",
                          hw_k.ulft_row+2, hw_k.ulft_col+1, NORMAL );
               j = getkey( );
            }
            window_control( &w_ptr, RESTORE, hw_k.ulft_col, hw_k.ulft_row,
                            hw_k.total_col, hw_k.total_row );
            break;
         case F8 :
            if ((fp = fopen( "PRN", "a" )) != NULL) {
               hw_k.ulft_col = 20;
               hw_k.ulft_row = 10;
               hw_k.total_col = 42;
               hw_k.total_row = 5;
               save_and_draw( &hw_k, print_head, &w_ptr );
               j = TRUE;
               for (i=0; i<hw->num_entries && j; i++) {
                  itoa( i+1, temp, 10 );
                  s_output( temp, hw_k.ulft_row+2, hw_k.ulft_col+16, NORMAL );
                  fprintf( fp, " %22s  = ", help[i].key+3 );
                  fprintf( fp, "  %s\n",  avail_func[help[i].func_index] );
                  if (kbhit()) {
                     j = getkey( );
                     if (j == ESC)
                        j = FALSE;
                     else
                        j = TRUE;
                  }
               }
               fprintf( fp, "\f" );
               fclose( fp );
               window_control( &w_ptr, RESTORE, hw_k.ulft_col, hw_k.ulft_row,
                               hw_k.total_col, hw_k.total_row );
            }
            break;
      }
      if (draw_page == TRUE) {
         show_key_def_list( hw, help );
         update_name = TRUE;
         change_color = TRUE;
      }
      row = hw->ulft_row + hw->dply_row + hw->v_row;
      if (update_name) {
         s_output( help[hw->select].key, row, col, NORMAL );
         s_output( avail_func[help[hw->select].func_index], row, col+31,
                      NORMAL );
      }
      if (change_color)
         hlight_line( col, row, hw->line_length, cfg.attr );
      *ch = getkey( );
      change_color = FALSE;
   }
   window_control( &w_ptr, RESTORE, hw->ulft_col, hw->ulft_row,
                   hw->total_col, hw->total_row );
}