Exemple #1
0
static void show_key(handle_t dest, memid_t key, bool full_path, bool recursive, uint16_t *indent)
  {
  char name[REG_NAME_MAX + 1];
  const char * path;
  if(full_path)
    path = get_full_path(key);
  else
    {
    reg_query_memid(key, 0, name, 0, 0);
    path = (char *)neutron_malloc(strlen(name)+1);
    strcpy((char *)path, name);
    }

  field_datatype type = 0;
  // must be 0 on first call
  memid_t child = 0;
  result_t result;

  while(succeeded(result = reg_enum_key(key, &type, 0, 0, REG_NAME_MAX + 1, name, &child)) && child != 0)
    {
    if (type > field_key)
      show_value(dest, key, type, name, indent, 0);

    // field_datatype has the field type, name is the child name
    type = 0;
    }

  type = field_key;
  child = 0;

  while(succeeded(result = reg_enum_key(key, &type, 0, 0, REG_NAME_MAX + 1, name, &child)))
    {
    do_indent(dest, *indent);
    stream_printf(dest, "dir    %s\r\n", name);
    *indent += 2;
    if(recursive)
      show_key(dest, child, false, true, indent);
    *indent -= 2;

    type = field_key;
    }

  }
Exemple #2
0
int main(int argc, char **argv)
{
	int fd;
	struct input_event ev;

	if (argc < 2) {
		printf("usage: %s <device>\n", argv[0]);
		return 1;
	}

	fd = open(argv[1], O_RDONLY);

	while (1) {
		read(fd, &ev, sizeof(struct input_event));

		if (ev.type == EV_KEY) {
			show_key(&ev);
		}
	}
}
Exemple #3
0
result_t ls_path_recursive_action(cli_t *context, const char * path)
  {
  uint16_t indent = 0;
  result_t result;
  memid_t key;
  handle_t matches = 0;

  bool recursive = strlen(context->tokens[2].token_buffer) != 0;

  if (strlen(path) == 0)
    {
    show_key(context->cfg.console_out, get_context(context), true, false, &indent);
    return s_ok;
    }

  // expand wildcards
  if (failed(result = match_path(context, path, true, &key, &matches)))
    return result;

  // work over each one.
  field_datatype dt = 0;
  memid_t child = 0;
  uint16_t i;
  char name[REG_NAME_MAX + 1];

  if (matches == 0)
    {
    // this is the case when a directory is given and no search
    show_key(context->cfg.console_out, key, false, recursive, &indent);
    }
  else
    {
    // decide what to do
    uint16_t len;
    if (failed(result = vector_count(matches, &len)))
      {
      kfree_split(matches);
      return result;
      }

    for (i = 0; i < len; i++)
      {
      const char * name;
      if (failed(result = vector_at(matches, i, &name)))
        {
        kfree_split(matches);
        return result;
        }

      if (failed(result = reg_query_child(key, name, &child, &dt, 0)))
        {
        if (result == e_not_found)
          continue;      // very weird!

        kfree_split(matches);
        return result;
        }

      if (dt > field_key)
        show_value(context->cfg.console_out, child, dt, name, &indent, 0);
      }

    bool needs_newline = true;

    // now the directories
    for (i = 0; i < len; i++)
      {
      const char * name;
      if (failed(result = vector_at(matches, i, &name)))
        {
        kfree_split(matches);
        return result;
        }

      if (failed(result = reg_query_child(key, name, &child, &dt, 0)))
        {
        if (result == e_not_found)
          continue;      // very weird!

        kfree_split(matches);
        return result;
        }

      if (dt == field_key)
        {
        if (needs_newline)
          {
          stream_puts(context->cfg.console_out, cr_lf);
          stream_printf(context->cfg.console_out, "dir %s\r\n", name);
          }
        indent += 2;
        show_key(context->cfg.console_out, child, false, recursive, &indent);
        }
      }

    kfree_split(matches);
    }
  return s_ok;
  }
Exemple #4
0
/* return TRUE if a command match, FALSE if not */
static TBOOLEAN
 show_two()
{
    if (almost_equals(c_token, "p$lot")) {
	(void) putc('\n', stderr);
	show_plot();
	c_token++;
    } else if (almost_equals(c_token, "par$ametric")) {
	(void) putc('\n', stderr);
	show_parametric();
	c_token++;
    } else if (almost_equals(c_token, "poi$ntsize")) {
	(void) putc('\n', stderr);
	show_pointsize();
	c_token++;
    } else if (almost_equals(c_token, "enc$oding")) {
	(void) putc('\n', stderr);
	show_encoding();
	c_token++;
    } else if (almost_equals(c_token, "pol$ar")) {
	(void) putc('\n', stderr);
	show_polar();
	c_token++;
    } else if (almost_equals(c_token, "an$gles")) {
	(void) putc('\n', stderr);
	show_angles();
	c_token++;
    } else if (almost_equals(c_token, "ti$cs")) {
	(void) putc('\n', stderr);
	show_tics(TRUE, TRUE, TRUE, TRUE, TRUE);
	c_token++;
    } else if (almost_equals(c_token, "tim$estamp")) {
	(void) putc('\n', stderr);
	show_xyzlabel("time", &timelabel);
	fprintf(stderr, "\twritten in %s corner\n", (timelabel_bottom ? "bottom" : "top"));
	if (timelabel_rotate)
	    fputs("\trotated if the terminal allows it\n\t", stderr);
	else
	    fputs("\tnot rotated\n\t", stderr);
	c_token++;
    } else if (almost_equals(c_token, "su$rface")) {
	(void) putc('\n', stderr);
	show_surface();
	c_token++;
    } else if (almost_equals(c_token, "hi$dden3d")) {
	(void) putc('\n', stderr);
	show_hidden3d();
	c_token++;
    } else if (almost_equals(c_token, "cla$bel")) {
	(void) putc('\n', stderr);
	show_label_contours();
	c_token++;
    } else if (almost_equals(c_token, "xti$cs")) {
	show_tics(TRUE, FALSE, FALSE, TRUE, FALSE);
	c_token++;
    } else if (almost_equals(c_token, "yti$cs")) {
	show_tics(FALSE, TRUE, FALSE, FALSE, TRUE);
	c_token++;
    } else if (almost_equals(c_token, "zti$cs")) {
	show_tics(FALSE, FALSE, TRUE, FALSE, FALSE);
	c_token++;
    } else if (almost_equals(c_token, "x2ti$cs")) {
	show_tics(FALSE, FALSE, FALSE, TRUE, FALSE);
	c_token++;
    } else if (almost_equals(c_token, "y2ti$cs")) {
	show_tics(FALSE, FALSE, FALSE, FALSE, TRUE);
	c_token++;
    } else if (almost_equals(c_token, "xdti$cs")) {
	show_tics(TRUE, FALSE, FALSE, TRUE, FALSE);
	c_token++;
    } else if (almost_equals(c_token, "ydti$cs")) {
	show_tics(FALSE, TRUE, FALSE, FALSE, TRUE);
	c_token++;
    } else if (almost_equals(c_token, "zdti$cs")) {
	show_tics(FALSE, FALSE, TRUE, FALSE, FALSE);
	c_token++;
    } else if (almost_equals(c_token, "x2dti$cs")) {
	show_tics(FALSE, FALSE, FALSE, TRUE, FALSE);
	c_token++;
    } else if (almost_equals(c_token, "y2dti$cs")) {
	show_tics(FALSE, FALSE, FALSE, FALSE, TRUE);
	c_token++;
    } else if (almost_equals(c_token, "xmti$cs")) {
	show_tics(TRUE, FALSE, FALSE, TRUE, FALSE);
	c_token++;
    } else if (almost_equals(c_token, "ymti$cs")) {
	show_tics(FALSE, TRUE, FALSE, FALSE, TRUE);
	c_token++;
    } else if (almost_equals(c_token, "zmti$cs")) {
	show_tics(FALSE, FALSE, TRUE, FALSE, FALSE);
	c_token++;
    } else if (almost_equals(c_token, "x2mti$cs")) {
	show_tics(FALSE, FALSE, FALSE, TRUE, FALSE);
	c_token++;
    } else if (almost_equals(c_token, "y2mti$cs")) {
	show_tics(FALSE, FALSE, FALSE, FALSE, TRUE);
	c_token++;
    } else if (almost_equals(c_token, "sa$mples")) {
	(void) putc('\n', stderr);
	show_samples();
	c_token++;
    } else if (almost_equals(c_token, "isosa$mples")) {
	(void) putc('\n', stderr);
	show_isosamples();
	c_token++;
    } else if (almost_equals(c_token, "si$ze")) {
	(void) putc('\n', stderr);
	show_size();
	c_token++;
    } else if (almost_equals(c_token, "orig$in")) {
	(void) putc('\n', stderr);
	show_origin();
	c_token++;
    } else if (almost_equals(c_token, "t$erminal")) {
	(void) putc('\n', stderr);
	show_term();
	c_token++;
    } else if (almost_equals(c_token, "rr$ange")) {
	(void) putc('\n', stderr);
	show_range(R_AXIS, rmin, rmax, autoscale_r, "r");
	c_token++;
    } else if (almost_equals(c_token, "tr$ange")) {
	(void) putc('\n', stderr);
	show_range(T_AXIS, tmin, tmax, autoscale_t, "t");
	c_token++;
    } else if (almost_equals(c_token, "ur$ange")) {
	(void) putc('\n', stderr);
	show_range(U_AXIS, umin, umax, autoscale_u, "u");
	c_token++;
    } else if (almost_equals(c_token, "vi$ew")) {
	(void) putc('\n', stderr);
	show_view();
	c_token++;
    } else if (almost_equals(c_token, "vr$ange")) {
	(void) putc('\n', stderr);
	show_range(V_AXIS, vmin, vmax, autoscale_v, "v");
	c_token++;
    } else if (almost_equals(c_token, "v$ariables")) {
	show_variables();
	c_token++;
    } else if (almost_equals(c_token, "ve$rsion")) {
	show_version(stderr);
    } else if (almost_equals(c_token, "xr$ange")) {
	(void) putc('\n', stderr);
	show_range(FIRST_X_AXIS, xmin, xmax, autoscale_x, "x");
	c_token++;
    } else if (almost_equals(c_token, "yr$ange")) {
	(void) putc('\n', stderr);
	show_range(FIRST_Y_AXIS, ymin, ymax, autoscale_y, "y");
	c_token++;
    } else if (almost_equals(c_token, "x2r$ange")) {
	(void) putc('\n', stderr);
	show_range(SECOND_X_AXIS, x2min, x2max, autoscale_x2, "x2");
	c_token++;
    } else if (almost_equals(c_token, "y2r$ange")) {
	(void) putc('\n', stderr);
	show_range(SECOND_Y_AXIS, y2min, y2max, autoscale_y2, "y2");
	c_token++;
    } else if (almost_equals(c_token, "zr$ange")) {
	(void) putc('\n', stderr);
	show_range(FIRST_Z_AXIS, zmin, zmax, autoscale_z, "z");
	c_token++;
    } else if (almost_equals(c_token, "z$ero")) {
	(void) putc('\n', stderr);
	show_zero();
	c_token++;
    } else if (almost_equals(c_token, "a$ll")) {
	c_token++;
	show_version(stderr);
	show_autoscale();
	show_bars();
	show_border();
	show_boxwidth();
	show_clip();
	show_contour();
	show_dgrid3d();
	show_mapping();
	(void) fprintf(stderr, "\tdummy variables are \"%s\" and \"%s\"\n",
		       dummy_var[0], dummy_var[1]);
	show_format();
	show_style("data", data_style);
	show_style("functions", func_style);
	show_grid();
	show_xzeroaxis();
	show_yzeroaxis();
	show_label(0);
	show_arrow(0);
	show_linestyle(0);
	show_keytitle();
	show_key();
	show_logscale();
	show_offsets();
	show_margin();
	show_output();
	show_parametric();
	show_pointsize();
	show_encoding();
	show_polar();
	show_angles();
	show_samples();
	show_isosamples();
	show_view();
	show_surface();
#ifndef LITE
	show_hidden3d();
#endif
	show_size();
	show_origin();
	show_term();
	show_tics(TRUE, TRUE, TRUE, TRUE, TRUE);
	show_mtics(mxtics, mxtfreq, "x");
	show_mtics(mytics, mytfreq, "y");
	show_mtics(mztics, mztfreq, "z");
	show_mtics(mx2tics, mx2tfreq, "x2");
	show_mtics(my2tics, my2tfreq, "y2");
	show_xyzlabel("time", &timelabel);
	if (parametric || polar) {
	    if (!is_3d_plot)
		show_range(T_AXIS, tmin, tmax, autoscale_t, "t");
	    else {
		show_range(U_AXIS, umin, umax, autoscale_u, "u");
		show_range(V_AXIS, vmin, vmax, autoscale_v, "v");
	    }
	}
	show_range(FIRST_X_AXIS, xmin, xmax, autoscale_x, "x");
	show_range(FIRST_Y_AXIS, ymin, ymax, autoscale_y, "y");
	show_range(SECOND_X_AXIS, x2min, x2max, autoscale_x2, "x2");
	show_range(SECOND_Y_AXIS, y2min, y2max, autoscale_y2, "y2");
	show_range(FIRST_Z_AXIS, zmin, zmax, autoscale_z, "z");
	show_xyzlabel("title", &title);
	show_xyzlabel("xlabel", &xlabel);
	show_xyzlabel("ylabel", &ylabel);
	show_xyzlabel("zlabel", &zlabel);
	show_xyzlabel("x2label", &x2label);
	show_xyzlabel("y2label", &y2label);
	show_datatype("xdata", FIRST_X_AXIS);
	show_datatype("ydata", FIRST_Y_AXIS);
	show_datatype("x2data", SECOND_X_AXIS);
	show_datatype("y2data", SECOND_Y_AXIS);
	show_datatype("zdata", FIRST_Z_AXIS);
	show_timefmt();
	show_locale();
	show_zero();
	show_missing();
	show_plot();
	show_variables();
	show_functions();
	c_token++;
    } else
	return (FALSE);
    return (TRUE);
}
Exemple #5
0
/* return TRUE if a command match, FALSE if not */
static TBOOLEAN
 show_one()
{
    if (almost_equals(c_token, "ac$tion_table") ||
	equals(c_token, "at")) {
	c_token++;
	show_at();
	c_token++;
    } else if (almost_equals(c_token, "ar$row")) {
	struct value a;
	int tag = 0;

	c_token++;
	if (!END_OF_COMMAND) {
	    tag = (int) real(const_express(&a));
	    if (tag <= 0)
		int_error("tag must be > zero", c_token);
	}
	(void) putc('\n', stderr);
	show_arrow(tag);
    } else if (almost_equals(c_token, "au$toscale")) {
	(void) putc('\n', stderr);
	show_autoscale();
	c_token++;
    } else if (almost_equals(c_token, "b$ars")) {
	(void) putc('\n', stderr);
	show_bars();
	c_token++;
    } else if (almost_equals(c_token, "bor$der")) {
	(void) putc('\n', stderr);
	show_border();
	c_token++;
    } else if (almost_equals(c_token, "box$width")) {
	(void) putc('\n', stderr);
	show_boxwidth();
	c_token++;
    } else if (almost_equals(c_token, "c$lip")) {
	(void) putc('\n', stderr);
	show_clip();
	c_token++;
    } else if (almost_equals(c_token, "ma$pping")) {
	(void) putc('\n', stderr);
	show_mapping();
	c_token++;
    } else if (almost_equals(c_token, "co$ntour") ||
	       almost_equals(c_token, "cn$trparam")) {
	(void) putc('\n', stderr);
	show_contour();
	c_token++;
    } else if (almost_equals(c_token, "da$ta")) {
	c_token++;
	if (!almost_equals(c_token, "s$tyle"))
	    int_error("expecting keyword 'style'", c_token);
	(void) putc('\n', stderr);
	show_style("data", data_style);
	c_token++;
    } else if (almost_equals(c_token, "dg$rid3d")) {
	(void) putc('\n', stderr);
	show_dgrid3d();
	c_token++;
    } else if (almost_equals(c_token, "du$mmy")) {
	(void) fprintf(stderr, "\n\tdummy variables are \"%s\" and \"%s\"\n",
		       dummy_var[0], dummy_var[1]);
	c_token++;
    } else if (almost_equals(c_token, "fo$rmat")) {
	show_format();
	c_token++;
    } else if (almost_equals(c_token, "fu$nctions")) {
	c_token++;
	if (almost_equals(c_token, "s$tyle")) {
	    (void) putc('\n', stderr);
	    show_style("functions", func_style);
	    c_token++;
	} else
	    show_functions();
    } else if (almost_equals(c_token, "lo$gscale")) {
	(void) putc('\n', stderr);
	show_logscale();
	c_token++;
    } else if (almost_equals(c_token, "of$fsets")) {
	(void) putc('\n', stderr);
	show_offsets();
	c_token++;
    } else if (almost_equals(c_token, "ma$rgin")) {
	(void) putc('\n', stderr);
	show_margin();
	c_token++;
    } else if (almost_equals(c_token, "o$utput")) {
	(void) putc('\n', stderr);
	show_output();
	c_token++;
    } else if (almost_equals(c_token, "tit$le")) {
	(void) putc('\n', stderr);
	show_xyzlabel("title", &title);
	c_token++;
    } else if (almost_equals(c_token, "mis$sing")) {
	(void) putc('\n', stderr);
	show_missing();
	c_token++;
    } else if (almost_equals(c_token, "xl$abel")) {
	(void) putc('\n', stderr);
	show_xyzlabel("xlabel", &xlabel);
	c_token++;
    } else if (almost_equals(c_token, "x2l$abel")) {
	(void) putc('\n', stderr);
	show_xyzlabel("x2label", &x2label);
	c_token++;
    } else if (almost_equals(c_token, "yl$abel")) {
	(void) putc('\n', stderr);
	show_xyzlabel("ylabel", &ylabel);
	c_token++;
    } else if (almost_equals(c_token, "y2l$abel")) {
	(void) putc('\n', stderr);
	show_xyzlabel("y2label", &y2label);
	c_token++;
    } else if (almost_equals(c_token, "zl$abel")) {
	(void) putc('\n', stderr);
	show_xyzlabel("zlabel", &zlabel);
	c_token++;
    } else if (almost_equals(c_token, "keyt$itle")) {
	(void) putc('\n', stderr);
	show_keytitle();
	c_token++;
    } else if (almost_equals(c_token, "xda$ta")) {
	(void) putc('\n', stderr);
	show_datatype("xdata", FIRST_X_AXIS);
	c_token++;
    } else if (almost_equals(c_token, "yda$ta")) {
	(void) putc('\n', stderr);
	show_datatype("ydata", FIRST_Y_AXIS);
	c_token++;
    } else if (almost_equals(c_token, "x2da$ta")) {
	(void) putc('\n', stderr);
	show_datatype("x2data", SECOND_X_AXIS);
	c_token++;
    } else if (almost_equals(c_token, "y2da$ta")) {
	(void) putc('\n', stderr);
	show_datatype("y2data", SECOND_Y_AXIS);
	c_token++;
    } else if (almost_equals(c_token, "zda$ta")) {
	(void) putc('\n', stderr);
	show_datatype("zdata", FIRST_Z_AXIS);
	c_token++;
    } else if (almost_equals(c_token, "timef$mt")) {
	(void) putc('\n', stderr);
	show_timefmt();
	c_token++;
    } else if (almost_equals(c_token, "loca$le")) {
	(void) putc('\n', stderr);
	show_locale();
	c_token++;
    } else if (almost_equals(c_token, "xzero$axis")) {
	(void) putc('\n', stderr);
	show_xzeroaxis();
	c_token++;
    } else if (almost_equals(c_token, "yzero$axis")) {
	(void) putc('\n', stderr);
	show_yzeroaxis();
	c_token++;
    } else if (almost_equals(c_token, "zeroa$xis")) {
	(void) putc('\n', stderr);
	show_xzeroaxis();
	show_yzeroaxis();
	c_token++;
    } else if (almost_equals(c_token, "la$bel")) {
	struct value a;
	int tag = 0;

	c_token++;
	if (!END_OF_COMMAND) {
	    tag = (int) real(const_express(&a));
	    if (tag <= 0)
		int_error("tag must be > zero", c_token);
	}
	(void) putc('\n', stderr);
	show_label(tag);
    } else if (almost_equals(c_token, "li$nestyle") || equals(c_token, "ls")) {
	struct value a;
	int tag = 0;

	c_token++;
	if (!END_OF_COMMAND) {
	    tag = (int) real(const_express(&a));
	    if (tag <= 0)
		int_error("tag must be > zero", c_token);
	}
	(void) putc('\n', stderr);
	show_linestyle(tag);
    } else if (almost_equals(c_token, "g$rid")) {
	(void) putc('\n', stderr);
	show_grid();
	c_token++;
    } else if (almost_equals(c_token, "mxt$ics")) {
	(void) putc('\n', stderr);
	show_mtics(mxtics, mxtfreq, "x");
	c_token++;
    } else if (almost_equals(c_token, "myt$ics")) {
	(void) putc('\n', stderr);
	show_mtics(mytics, mytfreq, "y");
	c_token++;
    } else if (almost_equals(c_token, "mzt$ics")) {
	(void) putc('\n', stderr);
	show_mtics(mztics, mztfreq, "z");
	c_token++;
    } else if (almost_equals(c_token, "mx2t$ics")) {
	(void) putc('\n', stderr);
	show_mtics(mx2tics, mx2tfreq, "x2");
	c_token++;
    } else if (almost_equals(c_token, "my2t$ics")) {
	(void) putc('\n', stderr);
	show_mtics(my2tics, my2tfreq, "y2");
	c_token++;
    } else if (almost_equals(c_token, "k$ey")) {
	(void) putc('\n', stderr);
	show_key();
	c_token++;
    } else
	return (FALSE);
    return TRUE;
}
/* Merge key from fkey (which is keyfile) at keypos with key from
 * fring (which is ringfile) at ringpos, appending result to out.
 */
static int mergekeys(FILE * fkey, char *keyfile, long keypos, FILE * fring,
		     char *ringfile, long *pringpos, FILE * out)
{
    long ringkeypos, keykeypos, ringpos;
    int ringpktlen, keypktlen;
    int status;
    byte ctb;
    int copying;
    boolean ring_compromise = FALSE;
    byte userid[256];

    /* First, copy the key packet itself, plus any comments or ctrls */
    ringkeypos = ringpos = *pringpos;
    fseek(fring, ringpos, SEEK_SET);
    (void) nextkeypacket(fring, &ctb);
    ringpktlen = ftell(fring) - ringpos;
    copyfilepos(fring, out, ringpktlen, ringpos);
    for (;;) {
	ringpos = ftell(fring);
	status = nextkeypacket(fring, &ctb);
	if (status < 0 || is_key_ctb(ctb) || ctb == CTB_USERID)
	    break;
	if (is_ctb_type(ctb, CTB_SKE_TYPE))
	    ring_compromise = TRUE;	/* compromise cert on keyring */
	ringpktlen = ftell(fring) - ringpos;
	copyfilepos(fring, out, ringpktlen, ringpos);
    }
    fseek(fring, ringpos, SEEK_SET);

    /* Now, ringpos points just past key packet and ctrl packet. */
    /* Advance keypos to the analogous location. */
    fseek(fkey, keypos, SEEK_SET);
    keykeypos = keypos;
    (void) nextkeypacket(fkey, &ctb);
    keypktlen = ftell(fkey) - keypos;	/* for check_key_sig() */
    for (;;) {
	keypos = ftell(fkey);
	status = nextkeypacket(fkey, &ctb);
	if (status < 0 || ctb == CTB_USERID || is_ctb_type(ctb, CTB_SKE_TYPE))
	    break;
    }
    if (!ring_compromise && is_ctb_type(ctb, CTB_SKE_TYPE)) {
	/* found a compromise cert on keyfile that is not in ringfile */
	word32 timestamp;
	byte sig_class;
	int cert_pktlen;

	cert_pktlen = ftell(fkey) - keypos;
	if (check_key_sig(fkey, keykeypos, keypktlen,
			  (char *) userid, fkey, keypos,
			  ringfile, (char *) userid, (byte *) & timestamp,
			  &sig_class) == 0 &&
	    sig_class == KC_SIGNATURE_BYTE) {
	    PascalToC((char *) userid);
	    fprintf(pgpout, LANG("Key revocation certificate from \"%s\".\n"),
		    LOCAL_CHARSET((char *) userid));
	    copyfilepos(fkey, out, cert_pktlen, keypos);
	    /* Show updates */
	    if (batchmode)
		show_key(fring, *pringpos, SHOW_CHANGE);
	    ++newrvks;
	} else
	    fprintf(pgpout,
     LANG("\n\007WARNING:  File '%s' contains bad revocation certificate.\n"),
		    keyfile);
    }
    fseek(fkey, keypos, SEEK_SET);

    /* Second, copy all keyfile userid's plus signatures that aren't
     * in ringfile.
     */

    copying = FALSE;
    for (;;) {
	/* Read next userid from keyfile; see if it is in ringfile;
	 * set copying true/false accordingly.  If copying is true
	 * and it is a userid or a signature, copy it.  Loop till hit
	 * a new key in keyfile, or EOF.
	 */
	keypos = ftell(fkey);
	status = readkeypacket(fkey, FALSE, &ctb, NULL, (char *) userid, NULL,
			       NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	if (status == -3) /* unrecoverable error: bad packet length etc. */
	    return status;
	keypktlen = ftell(fkey) - keypos;
	if (status == -1 || is_key_ctb(ctb))
	    break;		/* EOF or next key */
	if (status < 0)
	    continue;		/* bad packet, skip it */
	if (ctb == CTB_USERID) {
	    long userid_pos;
	    int userid_len;
	    PascalToC((char *) userid);
	    /* Set copying true if userid is not in the ringfile */
	    copying = (getpubuserid(ringfile, ringkeypos, userid, &userid_pos,
				    &userid_len, TRUE) < 0);
	    if (copying) {
		putc('\n', pgpout);
		fprintf(pgpout, LANG("New userid: \"%s\".\n"),
			LOCAL_CHARSET((char *) userid));
		fprintf(pgpout,
			LANG("\nWill be added to the following key:\n"));
		show_key(fring, *pringpos, 0);
		fprintf(pgpout, LANG("\nAdd this userid (y/N)? "));
		if (batchmode || getyesno('n')) {
		    ++newids;
		    /* Show an update string */
		    if (batchmode) {
			fprintf(pgpout, "\n");
			show_key(fring, *pringpos, SHOW_CHANGE);
		    }
		} else {
		    copying = FALSE;
		}
	    }
	}
	if (copying) {
	    if (ctb == CTB_USERID || is_ctb_type(ctb, CTB_SKE_TYPE)) {
		copyfilepos(fkey, out, keypktlen, keypos);
		if (publickey) {
		    if (is_ctb_type(ctb, CTB_SKE_TYPE))
			write_trust(out, KC_SIGTRUST_UNDEFINED);
		    else
			write_trust(out, KC_LEGIT_UNKNOWN);
		}
	    }
	}
    }

    /* Third, for all ring userid's, if not in keyfile, copy the userid
     * plus its dependant signatures.
     */
    fseek(fring, ringpos, SEEK_SET);
    /* Grab the keyID here */
    readkeypacket(fring, FALSE, &ctb, NULL, (char *) userid, NULL, NULL,
		  NULL, NULL, NULL, NULL, NULL, NULL);
    fseek(fring, ringpos, SEEK_SET);
    for (;;) {
	ringpos = ftell(fring);
	status = readkeypacket(fring, FALSE, &ctb, NULL,
			       (char *) userid, NULL, NULL,
			       NULL, NULL, NULL, NULL, NULL, NULL);
	ringpktlen = ftell(fring) - ringpos;
	if (status == -3)
	    return status;
	if (status == -1 || is_key_ctb(ctb))
	    break;
	if (ctb == CTB_USERID) {
	    long userid_pos;
	    int userid_len;
	    /* See if there is a match in keyfile */
	    PascalToC((char *) userid);
	    /* don't use substring match (exact_match = TRUE) */
	    if (getpubuserid(keyfile, keykeypos, userid,
			     &userid_pos, &userid_len, TRUE) >= 0) {
		if ((status = mergesigs(fkey, keyfile, userid_pos,
					fring, ringfile, &ringpos, out)) < 0)
		    return status;
		copying = FALSE;
	    } else {
		copying = TRUE;
	    }
	}
	if (copying) {
	    /* Copy ringfile userid and sigs to out */
	    copyfilepos(fring, out, ringpktlen, ringpos);
	}
    }				/* End of loop for each key in ringfile */
    fseek(fring, ringpos, SEEK_SET);
    *pringpos = ringpos;
    return 0;
}				/* mergekeys */