コード例 #1
0
ファイル: lvm.c プロジェクト: VladimirTyrin/libguestfs
int
do_vgcreate (const char *volgroup, char *const *physvols)
{
  int r, argc, i;
  CLEANUP_FREE char *err = NULL;
  CLEANUP_FREE const char **argv = NULL;

  argc = count_strings (physvols) + 3;
  argv = malloc (sizeof (char *) * (argc + 1));
  if (argv == NULL) {
    reply_with_perror ("malloc");
    return -1;
  }
  argv[0] = str_lvm;
  argv[1] = "vgcreate";
  argv[2] = volgroup;
  for (i = 3; i < argc+1; ++i)
    argv[i] = physvols[i-3];

  r = commandv (NULL, &err, (const char * const*) argv);
  if (r == -1) {
    reply_with_error ("%s", err);
    return -1;
  }

  udev_settle ();

  return 0;
}
コード例 #2
0
ファイル: debug.c プロジェクト: carriercomm/libguestfs
/* List files in the appliance. */
static char *
debug_ll (const char *subcmd, size_t argc, char *const *const argv)
{
  size_t len = count_strings (argv);
  const char *cargv[len+3];
  size_t i;
  int r;
  char *out;
  CLEANUP_FREE char *err = NULL;

  cargv[0] = str_ls;
  cargv[1] = "-la";
  for (i = 0; i < len; ++i)
    cargv[2+i] = argv[i];
  cargv[2+len] = NULL;

  r = commandv (&out, &err, (void *) cargv);
  if (r == -1) {
    reply_with_error ("ll: %s", err);
    free (out);
    return NULL;
  }

  return out;
}
コード例 #3
0
ファイル: lvm.c プロジェクト: VladimirTyrin/libguestfs
int
do_vg_activate (int activate, char *const *volgroups)
{
  int r, i, argc;
  CLEANUP_FREE char *err = NULL;
  CLEANUP_FREE const char **argv = NULL;

  argc = count_strings (volgroups) + 4;
  argv = malloc (sizeof (char *) * (argc+1));
  if (argv == NULL) {
    reply_with_perror ("malloc");
    return -1;
  }

  argv[0] = str_lvm;
  argv[1] = "vgchange";
  argv[2] = "-a";
  argv[3] = activate ? "y" : "n";
  for (i = 4; i < argc+1; ++i)
    argv[i] = volgroups[i-4];

  r = commandv (NULL, &err, (const char * const*) argv);
  if (r == -1) {
    reply_with_error ("vgchange: %s", err);
    return -1;
  }

  udev_settle ();

  return 0;
}
コード例 #4
0
ファイル: qemuopts.c プロジェクト: libguestfs/libguestfs
int
qemuopts_append_arg_list (struct qemuopts *qopts, const char *value)
{
  struct qopt *qopt;
  char **new_values;
  char *value_copy;
  size_t len;

  qopt = last_option (qopts);
  assert (qopt->type == QOPT_ARG_LIST);
  len = count_strings (qopt->values);

  value_copy = strdup (value);
  if (value_copy == NULL)
    return -1;

  new_values = realloc (qopt->values, (len+2) * sizeof (char *));
  if (new_values == NULL) {
    free (value_copy);
    return -1;
  }
  qopt->values = new_values;
  qopt->values[len] = value_copy;
  qopt->values[len+1] = NULL;
  return 0;
}
コード例 #5
0
ファイル: lvm.c プロジェクト: limohua/libguestfs
int
do_vgcreate (const char *volgroup, char *const *physvols)
{
  char *err;
  int r, argc, i;
  const char **argv;

  argc = count_strings (physvols) + 3;
  argv = malloc (sizeof (char *) * (argc + 1));
  if (argv == NULL) {
    reply_with_perror ("malloc");
    return -1;
  }
  argv[0] = "lvm";
  argv[1] = "vgcreate";
  argv[2] = volgroup;
  for (i = 3; i <= argc; ++i)
    argv[i] = physvols[i-3];

  r = commandv (NULL, &err, (const char * const*) argv);
  if (r == -1) {
    reply_with_error ("%s", err);
    free (err);
    free (argv);
    return -1;
  }

  free (err);
  free (argv);

  udev_settle ();

  return 0;
}
コード例 #6
0
ファイル: state.c プロジェクト: dsaravel/dex
static void cmd_default(const char *pf, char **args)
{
	close_state();
	if (no_syntax())
		return;

	ptr_array_add(&current_syntax->default_colors, copy_string_array(args, count_strings(args)));
}
コード例 #7
0
ファイル: domains.c プロジェクト: gaowanlong/libguestfs
/* Perform 'df' operation on the domain(s) given in the list. */
static void
multi_df (struct domain *domains, size_t n)
{
  size_t i;
  size_t nd;
  int r;
  char **devices;

  /* Add all the disks to the handle (since they were added in reverse
   * order, we must add them here in reverse too).
   */
  for (i = 0; i < n; ++i)
    add_disks_to_handle_reverse (domains[i].disks);

  /* Launch the handle. */
  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  devices = guestfs_list_devices (g);
  if (devices == NULL)
    exit (EXIT_FAILURE);

  /* Check the number of disks we think we added is the same as the
   * number of devices returned by libguestfs.
   */
  nd = 0;
  for (i = 0; i < n; ++i)
    nd += domains[i].nr_disks;
  assert (nd == count_strings (devices));

  nd = 0;
  for (i = 0; i < n; ++i) {
    /* So that &devices[nd] is a NULL-terminated list of strings. */
    char *p = devices[nd + domains[i].nr_disks];
    devices[nd + domains[i].nr_disks] = NULL;

    r = df_on_handle (domains[i].name, domains[i].uuid, &devices[nd], nd);

    /* Restore devices to original. */
    devices[nd + domains[i].nr_disks] = p;
    nd += domains[i].nr_disks;

    /* Something broke in df_on_handle.  Give up on the remaining
     * devices for this handle, but keep going on the next handle.
     */
    if (r == -1)
      break;
  }

  for (i = 0; devices[i] != NULL; ++i)
    free (devices[i]);
  free (devices);

  /* Reset the handle. */
  reset_guestfs_handle ();
}
コード例 #8
0
ファイル: structs.c プロジェクト: chemecse/piglit
/**
 * Verify that "bad" varying names produces the expected link error.
 *
 * When using interface blocks, this function also verifies that (a)
 * "bad" varying names produce a link error if they are prepended with
 * "Blk.", and (b) "good" varying names produce a link error if they
 * are *not* prepended with "Blk.".
 */
static enum piglit_result
test_errors()
{
	unsigned i;
	unsigned num_bad_varyings = count_strings(test->bad_varyings);
	unsigned num_good_varyings = count_strings(test->good_varyings);
	GLuint vs, fs;
	bool pass = true;

	prog = 0;
	vs = compile_shader(GL_VERTEX_SHADER, test->vs);
	fs = compile_shader(GL_FRAGMENT_SHADER, test->fs);

	/* Test one bad varying at a time to make sure they all
	 * produce the proper error.
	 */
	for (i = 0; i < num_bad_varyings; i++)
		pass = test_bad_varying(vs, fs, test->bad_varyings[i]) && pass;

	if (use_interface_blocks) {
		/* Test that the "bad" varyings fail if prepended with
		 * "Blk."
		 */
		const char **varyings
			= prepend_varyings("Blk.", test->bad_varyings);
		for (i = 0; i < num_bad_varyings; i++)
			pass = test_bad_varying(vs, fs, varyings[i]) && pass;
		free_varyings(varyings);

		/* Test that the "good" varyings fail if *not*
		 * prepended with "Blk."
		 */
		for (i = 0; i < num_good_varyings; i++) {
			pass = test_bad_varying(vs, fs, test->good_varyings[i])
				&& pass;
		}
	}

	glDeleteShader(vs);
	glDeleteShader(fs);

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
コード例 #9
0
ファイル: stat.c プロジェクト: AlphaStaxLLC/libguestfs
guestfs_int_statns_list *
do_internal_lstatnslist (const char *path, char *const *names)
{
  int path_fd;
  guestfs_int_statns_list *ret;
  size_t i, nr_names;

  nr_names = count_strings (names);

  ret = malloc (sizeof *ret);
  if (!ret) {
    reply_with_perror ("malloc");
    return NULL;
  }
  ret->guestfs_int_statns_list_len = nr_names;
  ret->guestfs_int_statns_list_val =
    calloc (nr_names, sizeof (guestfs_int_statns));
  if (ret->guestfs_int_statns_list_val == NULL) {
    reply_with_perror ("calloc");
    free (ret);
    return NULL;
  }

  CHROOT_IN;
  path_fd = open (path, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
  CHROOT_OUT;

  if (path_fd == -1) {
    reply_with_perror ("%s", path);
    free (ret->guestfs_int_statns_list_val);
    free (ret);
    return NULL;
  }

  for (i = 0; names[i] != NULL; ++i) {
    int r;
    struct stat statbuf;

    r = fstatat (path_fd, names[i], &statbuf, AT_SYMLINK_NOFOLLOW);
    if (r == -1)
      ret->guestfs_int_statns_list_val[i].st_ino = -1;
    else
      stat_to_statns (&ret->guestfs_int_statns_list_val[i], &statbuf);
  }

  if (close (path_fd) == -1) {
    reply_with_perror ("close: %s", path);
    free (ret->guestfs_int_statns_list_val);
    free (ret);
    return NULL;
  }

  return ret;
}
コード例 #10
0
ファイル: structs.c プロジェクト: chemecse/piglit
/**
 * Check that the buffer pointed to by \c readback contains the
 * expected transform feedback output data.
 */
static bool
check_outputs(const void *readback)
{
	const float *readback_f = readback;
	const int *readback_i = readback;
	unsigned num_good_varyings = count_strings(test->good_varyings);
	unsigned i;
	unsigned output_component = 0;
	unsigned float_index = 0;
	unsigned int_index = 0;
	bool pass = true;

	for (i = 0; i < num_good_varyings; i++) {
		const char *varying_name = test->good_varyings[i];
		unsigned varying_size = test->expected_sizes[i]
			* size_of_type(test->expected_types[i]);
		if (is_floating_type(test->expected_types[i])) {
			unsigned j;
			for (j = 0; j < varying_size; j++) {
				float actual = readback_f[output_component];
				float expected
					= test->expected_floats[float_index];
				if (actual != expected) {
					printf("Output %s element %u: "
					       "expected %f, got %f\n",
					       varying_name, j, expected,
					       actual);
					pass = false;
				}
				output_component++;
				float_index++;
			}
		} else {
			unsigned j;
			for (j = 0; j < varying_size; j++) {
				int actual = readback_i[output_component];
				int expected = test->expected_ints[int_index];
				if (actual != expected) {
					printf("Output %s element %u: "
					       "expected %i, got %i\n",
					       varying_name, j, expected,
					       actual);
					pass = false;
				}
				output_component++;
				int_index++;
			}
		}
	}

	return pass;
}
コード例 #11
0
ファイル: copy-over.c プロジェクト: will-Do/libguestfs
/* This function deals with the complexity of adding the domain,
 * launching the handle, and mounting up filesystems.  See
 * 'examples/inspect-vm.c' to understand how this works.
 */
static int
open_guest (guestfs_h *g, const char *dom, int readonly)
{
    char **roots, *root, **mountpoints;
    size_t i;

    /* Use libvirt to find the guest disks and add them to the handle. */
    if (guestfs_add_domain (g, dom,
                            GUESTFS_ADD_DOMAIN_READONLY, readonly,
                            -1) == -1)
        return -1;

    if (guestfs_launch (g) == -1)
        return -1;

    /* Inspect the guest, looking for operating systems. */
    roots = guestfs_inspect_os (g);
    if (roots == NULL)
        return -1;

    if (roots[0] == NULL || roots[1] != NULL) {
        fprintf (stderr, "copy-over: %s: no operating systems or multiple operating systems found\n", dom);
        return -1;
    }

    root = roots[0];

    /* Mount up the filesystems (like 'guestfish -i'). */
    mountpoints = guestfs_inspect_get_mountpoints (g, root);
    if (mountpoints == NULL)
        return -1;

    qsort (mountpoints, count_strings (mountpoints) / 2, 2 * sizeof (char *),
           compare_keys_len);
    for (i = 0; mountpoints[i] != NULL; i += 2) {
        /* Ignore failures from this call, since bogus entries can
         * appear in the guest's /etc/fstab.
         */
        (readonly ? guestfs_mount_ro : guestfs_mount)
        (g, mountpoints[i+1], mountpoints[i]);
        free (mountpoints[i]);
        free (mountpoints[i+1]);
    }

    free (mountpoints);

    free (root);
    free (roots);

    /* Everything ready, no error. */
    return 0;
}
コード例 #12
0
ファイル: structs.c プロジェクト: chemecse/piglit
/**
 * Compute the expected number of transform feedback outputs for the
 * current test.  This is used to size the transform feedback buffer.
 */
static unsigned
count_outputs()
{
	unsigned num_good_varyings = count_strings(test->good_varyings);
	unsigned i;
	unsigned num_outputs = 0;

	for (i = 0; i < num_good_varyings; i++) {
		num_outputs += size_of_type(test->expected_types[i])
			* test->expected_sizes[i];
	}
	return num_outputs;
}
コード例 #13
0
ファイル: qemuopts.c プロジェクト: libguestfs/libguestfs
int
qemuopts_end_arg_list (struct qemuopts *qopts)
{
  struct qopt *qopt;
  size_t len;

  qopt = last_option (qopts);
  assert (qopt->type == QOPT_ARG_LIST);
  len = count_strings (qopt->values);
  if (len == 0)
    return -1;

  return 0;
}
コード例 #14
0
ファイル: structs.c プロジェクト: chemecse/piglit
/**
 * Verify that glGetTransformFeedbackVarying() returns the proper
 * information for all "good" varying names.
 *
 * The program should already be linked and stored in the global \c
 * prog.
 */
static enum piglit_result
test_gets()
{
	unsigned i;
	unsigned num_good_varyings = count_strings(test->good_varyings);
	const char **varyings;
	bool pass = true;

	if (use_interface_blocks)
		varyings = prepend_varyings("Blk.", test->good_varyings);
	else
		varyings = test->good_varyings;

	for (i = 0; i < num_good_varyings; i++) {
		const char *exp_name = varyings[i];
		GLsizei exp_length = strlen(exp_name);
		GLsizei exp_size = test->expected_sizes[i];
		GLenum exp_type = test->expected_types[i];
		GLsizei length;
		GLsizei size;
		GLenum type;
		char name[100];
		glGetTransformFeedbackVarying(prog, i, sizeof(name), &length,
					      &size, &type, name);
		if (length != exp_length || size != exp_size
		    || type != exp_type || strcmp(name, exp_name) != 0) {
			pass = false;
			printf("glGetTransformFeedbackVarying() returned "
			       "unexpected data for varying %u:\n", i);
			printf("  length: expected %u, got %u\n",
			       exp_length, length);
			printf("  size: expected %u, got %u\n",
			       exp_size, size);
			printf("  type: expected %u (%s), got %u (%s)\n",
			       exp_type, piglit_get_gl_enum_name(exp_type),
			       type, piglit_get_gl_enum_name(type));
			printf("  name: expected %s, got %s\n",
			       exp_name, name);
		}
	}

	if (use_interface_blocks)
		free_varyings(varyings);

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
コード例 #15
0
ファイル: vifm.c プロジェクト: phantasea/vifm
/* Handles arguments received from remote instance. */
static void
parse_received_arguments(char *argv[])
{
	args_t args = {};

	(void)vifm_chdir(argv[0]);
	opterr = 0;
	args_parse(&args, count_strings(argv), argv, argv[0]);
	args_process(&args, 0);

	exec_startup_commands(&args);
	args_free(&args);

	if(NONE(vle_mode_is, NORMAL_MODE, VIEW_MODE))
	{
		return;
	}

#ifdef _WIN32
	SwitchToThisWindow(GetConsoleWindow(), TRUE);
	BringWindowToTop(GetConsoleWindow());
	SetForegroundWindow(GetConsoleWindow());
#endif

	if(view_needs_cd(&lwin, args.lwin_path))
	{
		remote_cd(&lwin, args.lwin_path, args.lwin_handle);
	}

	if(view_needs_cd(&rwin, args.rwin_path))
	{
		remote_cd(&rwin, args.rwin_path, args.rwin_handle);
	}

	if(need_to_switch_active_pane(args.lwin_path, args.rwin_path))
	{
		change_window();
	}

	/* XXX: why force clearing of the statusbar? */
	ui_sb_clear();
	curr_stats.save_msg = 0;
}
コード例 #16
0
ファイル: structs.c プロジェクト: chemecse/piglit
/**
 * Link the appropriate set of shaders for running a positive test,
 * calling glTransformFeedbackVaryings() to set up transform feedback.
 */
static void
link_shaders(bool use_fs)
{
	GLuint vs;
	const char **varyings;
	prog = glCreateProgram();
	vs = compile_shader(GL_VERTEX_SHADER, test->vs);
	glAttachShader(prog, vs);
	glDeleteShader(vs);
	if (use_fs) {
		GLuint fs = compile_shader(GL_FRAGMENT_SHADER, test->fs);
		glAttachShader(prog, fs);
		glDeleteShader(fs);
	} else {
#ifdef PIGLIT_USE_OPENGL_ES3
		GLuint fs = compile_shader(GL_FRAGMENT_SHADER, generic_gles3_fs_text);
		glAttachShader(prog, fs);
		glDeleteShader(fs);
#endif
	}
	if (use_interface_blocks)
		varyings = prepend_varyings("Blk.", test->good_varyings);
	else
		varyings = test->good_varyings;
	glTransformFeedbackVaryings(prog, count_strings(test->good_varyings),
				    (const GLchar **) varyings,
				    GL_INTERLEAVED_ATTRIBS);
	if (use_interface_blocks)
		free_varyings(varyings);
	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		glDeleteProgram(prog);
		report_result(PIGLIT_FAIL);
	}
	glBindAttribLocation(prog, VERTEX_ATTRIB_POS, "pos");
	glLinkProgram(prog);
	if (!piglit_link_check_status(prog)) {
		glDeleteProgram(prog);
		report_result(PIGLIT_FAIL);
	}
}
コード例 #17
0
ファイル: frtxtspn.C プロジェクト: ralfbrown/framepac
FrTextSpans::FrTextSpans(const FrObject *span_defn, FrCharEncoding enc,
			 const char *word_delim)
{
   clear() ;
   if (span_defn)
      {
      if (span_defn->stringp())
	 makeWordSpans(((FrString*)span_defn)->stringValue(),enc,word_delim) ;
      else if (span_defn->symbolp())
	 makeWordSpans(((FrSymbol*)span_defn)->symbolName(),enc,word_delim) ;
      else if (span_defn->consp())
	 {
	 // parse the given list into the original text and individual
	 //   spans
	 const FrList *defn = (FrList*)span_defn ;
	 size_t num_strings = count_strings(defn) ;
	 size_t defn_len = defn->simplelistlength() ;
	 // if the list consists solely of FrString or FrSymbol, then we
	 //   concatenate them to form the original text and make each one
	 //   a separate span
	 if (num_strings == defn_len)
	    makeWordSpans(defn) ;
	 // if there's exactly one FrString or FrSymbol, that is our original
	 //   text, and the rest of the list elements define the spans over
	 //   that text
	 else if (num_strings == 1)
	    parseSpans(defn) ;
	 else
	    FrWarning("span definition for FrTextSpans ctor must contain\n"
		      "\teither exactly one string or only strings") ;
	 }
      else
	 {
	 FrWarning("invalid span definition given to FrTextSpans ctor") ;
	 }
      }
   return ;
}
コード例 #18
0
ファイル: utils.c プロジェクト: angrygorilla/febootstrap
/* Sort a list of strings, in place, with the comparison function supplied. */
void
sort (char **strings, int (*compare) (const void *, const void *))
{
  qsort (strings, count_strings (strings), sizeof (char *), compare);
}
コード例 #19
0
ファイル: md.c プロジェクト: limohua/libguestfs
/* Takes optional arguments, consult optargs_bitmask. */
int
do_md_create (const char *name, char *const *devices,
              int64_t missingbitmap, int nrdevices, int spare,
              int64_t chunk, const char *level)
{
  char nrdevices_s[32];
  char spare_s[32];
  char chunk_s[32];
  size_t j;
  int r;
  char *err;
  uint64_t umissingbitmap = (uint64_t) missingbitmap;

  /* Check the optional parameters and set defaults where appropriate. */
  if (!(optargs_bitmask & GUESTFS_MD_CREATE_MISSINGBITMAP_BITMASK))
    umissingbitmap = 0;

  if (optargs_bitmask & GUESTFS_MD_CREATE_SPARE_BITMASK) {
    if (spare < 0) {
      reply_with_error ("spare must not be negative");
      return -1;
    }
  }
  else
    spare = 0;

  if (optargs_bitmask & GUESTFS_MD_CREATE_NRDEVICES_BITMASK) {
    if (nrdevices < 2) {
      reply_with_error ("nrdevices is less than 2");
      return -1;
    }
  }
  else
    nrdevices = count_strings (devices) + count_bits (umissingbitmap);

  if (optargs_bitmask & GUESTFS_MD_CREATE_LEVEL_BITMASK) {
    if (STRNEQ (level, "linear") && STRNEQ (level, "raid0") &&
        STRNEQ (level, "0") && STRNEQ (level, "stripe") &&
        STRNEQ (level, "raid1") && STRNEQ (level, "1") &&
        STRNEQ (level, "mirror") &&
        STRNEQ (level, "raid4") && STRNEQ (level, "4") &&
        STRNEQ (level, "raid5") && STRNEQ (level, "5") &&
        STRNEQ (level, "raid6") && STRNEQ (level, "6") &&
        STRNEQ (level, "raid10") && STRNEQ (level, "10")) {
      reply_with_error ("unknown level parameter: %s", level);
      return -1;
    }
  }
  else
    level = "raid1";

  if (optargs_bitmask & GUESTFS_MD_CREATE_CHUNK_BITMASK) {
    /* chunk is bytes in the libguestfs API, but K when we pass it to mdadm */
    if ((chunk & 1023) != 0) {
      reply_with_error ("chunk size must be a multiple of 1024 bytes");
      return -1;
    }
  }

  /* Check invariant. */
  if (count_strings (devices) + count_bits (umissingbitmap) !=
      (size_t) (nrdevices + spare)) {
    reply_with_error ("devices (%zu) + bits set in missingbitmap (%zu) is not equal to nrdevices (%d) + spare (%d)",
                      count_strings (devices), count_bits (umissingbitmap),
                      nrdevices, spare);
    return -1;
  }

  size_t MAX_ARGS = nrdevices + 16;
  const char *argv[MAX_ARGS];
  size_t i = 0;

  ADD_ARG (argv, i, "mdadm");
  ADD_ARG (argv, i, "--create");
  /* --run suppresses "Continue creating array" question */
  ADD_ARG (argv, i, "--run");
  ADD_ARG (argv, i, name);
  ADD_ARG (argv, i, "--level");
  ADD_ARG (argv, i, level);
  ADD_ARG (argv, i, "--raid-devices");
  snprintf (nrdevices_s, sizeof nrdevices_s, "%d", nrdevices);
  ADD_ARG (argv, i, nrdevices_s);
  if (optargs_bitmask & GUESTFS_MD_CREATE_SPARE_BITMASK) {
    ADD_ARG (argv, i, "--spare-devices");
    snprintf (spare_s, sizeof spare_s, "%d", spare);
    ADD_ARG (argv, i, spare_s);
  }
  if (optargs_bitmask & GUESTFS_MD_CREATE_CHUNK_BITMASK) {
    ADD_ARG (argv, i, "--chunk");
    snprintf (chunk_s, sizeof chunk_s, "%" PRIi64, chunk / 1024);
    ADD_ARG (argv, i, chunk_s);
  }

  /* Add devices and "missing". */
  j = 0;
  while (devices[j] != NULL || umissingbitmap != 0) {
    if (umissingbitmap & 1)
      ADD_ARG (argv, i, "missing");
    else {
      ADD_ARG (argv, i, devices[j]);
      j++;
    }
    umissingbitmap >>= 1;
  }

  ADD_ARG (argv, i, NULL);

  r = commandv (NULL, &err, argv);
  if (r == -1) {
    reply_with_error ("mdadm: %s: %s", name, err);
    free (err);
    return -1;
  }

  free (err);

  udev_settle ();

  return 0;
}
コード例 #20
0
ファイル: stat.c プロジェクト: gaowanlong/libguestfs
guestfs_int_stat_list *
do_lstatlist (const char *path, char *const *names)
{
  int path_fd;
  guestfs_int_stat_list *ret;
  size_t i, nr_names;

  nr_names = count_strings (names);

  ret = malloc (sizeof *ret);
  if (!ret) {
    reply_with_perror ("malloc");
    return NULL;
  }
  ret->guestfs_int_stat_list_len = nr_names;
  ret->guestfs_int_stat_list_val = calloc (nr_names, sizeof (guestfs_int_stat));
  if (ret->guestfs_int_stat_list_val == NULL) {
    reply_with_perror ("malloc");
    free (ret);
    return NULL;
  }

  CHROOT_IN;
  path_fd = open (path, O_RDONLY | O_DIRECTORY);
  CHROOT_OUT;

  if (path_fd == -1) {
    reply_with_perror ("%s", path);
    free (ret->guestfs_int_stat_list_val);
    free (ret);
    return NULL;
  }

  for (i = 0; names[i] != NULL; ++i) {
    int r;
    struct stat statbuf;

    r = fstatat (path_fd, names[i], &statbuf, AT_SYMLINK_NOFOLLOW);
    if (r == -1)
      ret->guestfs_int_stat_list_val[i].ino = -1;
    else {
      ret->guestfs_int_stat_list_val[i].dev = statbuf.st_dev;
      ret->guestfs_int_stat_list_val[i].ino = statbuf.st_ino;
      ret->guestfs_int_stat_list_val[i].mode = statbuf.st_mode;
      ret->guestfs_int_stat_list_val[i].nlink = statbuf.st_nlink;
      ret->guestfs_int_stat_list_val[i].uid = statbuf.st_uid;
      ret->guestfs_int_stat_list_val[i].gid = statbuf.st_gid;
      ret->guestfs_int_stat_list_val[i].rdev = statbuf.st_rdev;
      ret->guestfs_int_stat_list_val[i].size = statbuf.st_size;
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
      ret->guestfs_int_stat_list_val[i].blksize = statbuf.st_blksize;
#else
      ret->guestfs_int_stat_list_val[i].blksize = -1;
#endif
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
      ret->guestfs_int_stat_list_val[i].blocks = statbuf.st_blocks;
#else
      ret->guestfs_int_stat_list_val[i].blocks = -1;
#endif
      ret->guestfs_int_stat_list_val[i].atime = statbuf.st_atime;
      ret->guestfs_int_stat_list_val[i].mtime = statbuf.st_mtime;
      ret->guestfs_int_stat_list_val[i].ctime = statbuf.st_ctime;
    }
  }

  if (close (path_fd) == -1) {
    reply_with_perror ("close: %s", path);
    free (ret->guestfs_int_stat_list_val);
    free (ret);
    return NULL;
  }

  return ret;
}
コード例 #21
0
ファイル: inspect-vm.c プロジェクト: AlphaStaxLLC/libguestfs
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  const char *disk;
  char **roots, *root, *str, **mountpoints, **lines;
  size_t i, j;

  if (argc != 2) {
    fprintf (stderr, "usage: inspect_vm disk.img\n");
    exit (EXIT_FAILURE);
  }
  disk = argv[1];

  g = guestfs_create ();
  if (g == NULL) {
    perror ("failed to create libguestfs handle");
    exit (EXIT_FAILURE);
  }

  /* Attach the disk image read-only to libguestfs. */
  if (guestfs_add_drive_opts (g, disk,
			      /* GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", */
			      GUESTFS_ADD_DRIVE_OPTS_READONLY, 1,
			      -1) /* this marks end of optional arguments */
      == -1)
    exit (EXIT_FAILURE);

  /* Run the libguestfs back-end. */
  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  /* Ask libguestfs to inspect for operating systems. */
  roots = guestfs_inspect_os (g);
  if (roots == NULL)
    exit (EXIT_FAILURE);
  if (roots[0] == NULL) {
    fprintf (stderr, "inspect_vm: no operating systems found\n");
    exit (EXIT_FAILURE);
  }

  for (j = 0; roots[j] != NULL; ++j) {
    root = roots[j];

    printf ("Root device: %s\n", root);

    /* Print basic information about the operating system. */
    str = guestfs_inspect_get_product_name (g, root);
    if (str)
      printf ("  Product name: %s\n", str);
    free (str);

    printf ("  Version:      %d.%d\n",
            guestfs_inspect_get_major_version (g, root),
            guestfs_inspect_get_minor_version (g, root));

    str = guestfs_inspect_get_type (g, root);
    if (str)
      printf ("  Type:         %s\n", str);
    free (str);
    str = guestfs_inspect_get_distro (g, root);
    if (str)
      printf ("  Distro:       %s\n", str);
    free (str);

    /* Mount up the disks, like guestfish -i.
     *
     * Sort keys by length, shortest first, so that we end up
     * mounting the filesystems in the correct order.
     */
    mountpoints = guestfs_inspect_get_mountpoints (g, root);
    if (mountpoints == NULL)
      exit (EXIT_FAILURE);

    qsort (mountpoints, count_strings (mountpoints) / 2, 2 * sizeof (char *),
           compare_keys_len);
    for (i = 0; mountpoints[i] != NULL; i += 2) {
      /* Ignore failures from this call, since bogus entries can
       * appear in the guest's /etc/fstab.
       */
      guestfs_mount_ro (g, mountpoints[i+1], mountpoints[i]);
      free (mountpoints[i]);
      free (mountpoints[i+1]);
    }
    free (mountpoints);

    /* If /etc/issue.net file exists, print up to 3 lines. */
    if (guestfs_is_file (g, "/etc/issue.net") > 0) {
      printf ("--- /etc/issue.net ---\n");
      lines = guestfs_head_n (g, 3, "/etc/issue.net");
      if (lines == NULL)
        exit (EXIT_FAILURE);
      for (i = 0; lines[i] != NULL; ++i) {
        printf ("%s\n", lines[i]);
        free (lines[i]);
      }
      free (lines);
    }

    /* Unmount everything. */
    if (guestfs_umount_all (g) == -1)
      exit (EXIT_FAILURE);

    free (root);
  }
  free (roots);

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
コード例 #22
0
ファイル: parted.c プロジェクト: mdbooth/libguestfs
int
do_part_get_bootable (const char *device, int partnum)
{
  if (partnum <= 0) {
    reply_with_error ("partition number must be >= 1");
    return -1;
  }

  int parted_has_m_opt = test_parted_m_opt ();
  if (parted_has_m_opt == -1)
    return -1;

  char *out = print_partition_table (device, parted_has_m_opt);
  if (!out)
    return -1;

  char **lines = split_lines (out);
  free (out);

  if (!lines)
    return -1;

  if (parted_has_m_opt) {
    /* New-style parsing using the "machine-readable" format from
     * 'parted -m'.
     *
     * Partitions may not be in any order, so we have to look for
     * the matching partition number (RHBZ#602997).
     */
    if (lines[0] == NULL || STRNEQ (lines[0], "BYT;")) {
      reply_with_error ("unknown signature, expected \"BYT;\" as first line of the output: %s",
                        lines[0] ? lines[0] : "(signature was null)");
      free_strings (lines);
      return -1;
    }

    if (lines[1] == NULL) {
      reply_with_error ("parted didn't return a line describing the device");
      free_strings (lines);
      return -1;
    }

    size_t row;
    int pnum;
    for (row = 2; lines[row] != NULL; ++row) {
      if (sscanf (lines[row], "%d:", &pnum) != 1) {
        reply_with_error ("could not parse row from output of parted print command: %s", lines[row]);
        free_strings (lines);
        return -1;
      }
      if (pnum == partnum)
        break;
    }

    if (lines[row] == NULL) {
      reply_with_error ("partition number %d not found", partnum);
      free_strings (lines);
      return -1;
    }

    char *boot = get_table_field (lines[row], 6);
    if (boot == NULL) {
      free_strings (lines);
      return -1;
    }

    int r = STREQ (boot, "boot");

    free (boot);
    free_strings (lines);

    return r;
  }
  else {
    /* Old-style: First look for the line matching "^Number". */
    size_t start = 0, header, row;

    for (row = 0; lines[row] != NULL; ++row)
      if (STRPREFIX (lines[row], "Number")) {
        start = row+1;
        header = row;
        break;
      }

    if (start == 0) {
      reply_with_error ("parted output has no \"Number\" line");
      free_strings (lines);
      return -1;
    }

    /* Now we have to look at the column number of the "Flags" field.
     * This is because parted's output has no way to represent a
     * missing field except as whitespace, so we cannot just count
     * fields from the left.  eg. The "File system" field is often
     * missing in the output.
     */
    char *p = strstr (lines[header], "Flags");
    if (!p) {
      reply_with_error ("parted output has no \"Flags\" field");
      free_strings (lines);
      return -1;
    }
    size_t col = p - lines[header];

    /* Look for the line corresponding to this partition number. */
    row = start + partnum - 1;
    if (row >= count_strings (lines) || !STRPREFIX (lines[row], " ")) {
      reply_with_error ("partition number out of range: %d", partnum);
      free_strings (lines);
      return -1;
    }

    int r = STRPREFIX (&lines[row][col], "boot");
    free_strings (lines);
    return r;
  }
}
コード例 #23
0
ファイル: engine-gpgme.c プロジェクト: tuvell/gpgol
/* Return an array of gpgme key objects derived from thye list of
   strings in RECPIENTS. */
static gpg_error_t
prepare_recipient_keys (gpgme_key_t **r_keys, char **recipients, HWND hwnd)
{
  gpg_error_t err;
  gpgme_key_t *keys = NULL;
  char **unknown = NULL;
  size_t n_keys, n_unknown, n_recp;
  int i;

  *r_keys = NULL;
  if (op_lookup_keys (recipients, &keys, &unknown))
    {
      log_debug ("%s:%s: leave (lookup keys failed)\n", SRCNAME, __func__);
      return gpg_error (GPG_ERR_GENERAL);  
    }

  n_recp = count_strings (recipients);
  n_keys = count_keys (keys);
  n_unknown = count_strings (unknown);

  log_debug ("%s:%s: found %d recipients, need %d, unknown=%d\n",
             SRCNAME, __func__, (int)n_keys, (int)n_recp, (int)n_unknown);
  
  if (n_keys != n_recp)
    {
      unsigned int opts;
      gpgme_key_t *keys2;

      log_debug ("%s:%s: calling recipient_dialog_box2", SRCNAME, __func__);
      opts = recipient_dialog_box2 (keys, unknown, &keys2);
      release_key_array (keys);
      keys = keys2;
      if ( (opts & OPT_FLAG_CANCEL) ) 
        {
          err = gpg_error (GPG_ERR_CANCELED);
          goto leave;
	}
    }


  /* If a default key has been set, add it to the list of keys.  Check
     that the key is actually available. */
  if (opt.enable_default_key && opt.default_key && *opt.default_key)
    {
      gpgme_key_t defkey;
      
      defkey = op_get_one_key (opt.default_key);
      if (!defkey)
        {
          MessageBox (hwnd,
                 _("The configured default encryption certificate is not "
                   "available or does not unambigiously specify one. "
                   "Please fix this in the option dialog.\n\n"
                   "This message won't be be encrypted to this certificate!"),
                   _("Encryption"), MB_ICONWARNING|MB_OK);
        }
      else
        {
          gpgme_key_t *tmpkeys;

          n_keys = count_keys (keys) + 1;
          tmpkeys = xcalloc (n_keys+1, sizeof *tmpkeys);
          for (i = 0; keys[i]; i++) 
            {
              tmpkeys[i] = keys[i];
              gpgme_key_ref (tmpkeys[i]);
            }
          tmpkeys[i++] = defkey;
          tmpkeys[i] = NULL;
          release_key_array (keys);
          keys = tmpkeys;
        }
    }
  
  if (keys)
    {
      for (i=0; keys[i]; i++)
        log_debug ("%s:%s: recp.%d 0x%s %s\n", SRCNAME, __func__,
                   i, keyid_from_key (keys[i]), userid_from_key (keys[i]));
    }
  *r_keys = keys;
  keys = NULL;
  err = 0;

 leave:
  release_key_array (keys);
  return err;
}